首页 文章

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

提问于
浏览
9

我是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数据渲染一次?

2 回答

  • 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>
    

    现在你所需要做的就是在创造时“保湿”你的商店 .

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

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

相关问题