使用ComponentDidMount中的API调用来更新Redux存储使我的组件呈现两次

时间:2016-01-13 06:51:09

标签: reactjs redux

我是React / Redux的新手。任何帮助都会很棒。我有一个组件,它在ComponentDidMount上进行API调用以获取数据,然后更新我的Redux存储。该组件还使用connect来获取Redux状态,并将其作为props传递给哑组件。

componentDidMount() {
  this.props.dispatch(fetchSite()) //this triggers the api call and updates the redux store.
}

return ( 
  <div>
    <Child
        myprop={this.props.name}
    />
  </div>

export default connect((state) => ({name: state.name}))(Container);

因为componentDidMount在组件渲染后触发,它将渲染,运行api,然后重新渲染,因为api改变了redux状态。这使得组件呈现两次。第一次没有任何数据,然后第二次有来自api的好数据。

有更好的方法吗?

由于我的Child组件基于它传递的props呈现不同的东西,因此它在第一次呈现时会短暂地显示不同的东西。然后,当api更新商店并重新呈现组件时,它会再次显示不同的内容。它是两种不同状态的闪烁。

有没有办法让它只使用正确的API数据渲染一次?

3 个答案:

答案 0 :(得分:7)

让我们考虑一下这里发生了什么。

页面及其所有资源都在浏览器中加载,脚本运行并呈现所有React组件。只有在他们进行渲染后才能获取您的数据。所以当然会有一个初始状态,然后是一个加载状态。

那么在数据进入之前你如何处理应用程序的状态呢?

您已经表达了您对使用空白数据展示应用程序的可理解的不喜欢。您可以延迟应用程序的呈现,直到数据到达。但这会导致糟糕的用户体验。在发生任何事情之前,他们可能会在几秒钟内盯着空白页面。

或者那里有旧的装载技巧。在初始状态下,您可能会遇到类似isLoading: true的内容。这将对应于React组件中的一些可视加载指示器(传统上是旋转的GIF图像)。如果您必须通过AJAX加载数据,这肯定是最佳选择。

更好的方法

但事情就是这样:你不需要在初始状态下使用AJAX。您可以通过将数据附加到页面来完全避免此延迟。

<!-- place this BEFORE your Redux/React scripts -->
<script>
    // This object must match the shape of your Redux reducer state
    var __INITIAL_DATA__ = {
        todos: [{
            name: "Gather requirements",
            done: false
        }, {
            name: "Write code",
            done: false
        }]
    };
</script>

现在你需要做的就是&#34;保湿&#34;你的商店在创作时。

const store = createStore(rootReducer, window.__INITIAL_DATA__);

答案 1 :(得分:0)

更好的方法是让fetchSite返回一些模拟信息,立即指示您的组件尚未完成。您还应该在componentWillMount中调度此操作。如果fetchSite返回加载指示符数据,则渲染应该只返回null。当fetchSite实际完成时,它将触发商店更新,组件将在componentWillMount中的下一个fetchSite调用中获取实际数据。

答案 2 :(得分:0)

我这边的另一种情况是,我正在用React Lazy加载组件。在已加载的组件中,当我对redux使用异步调度时,多次调用componentDidMount / useEffect。因此,当我删除React Lazy之后,问题就解决了。

相关问题