Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/reactjs/21.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Reactjs 反应+;Redux:处理调度后逻辑的正确方法_Reactjs_Redux - Fatal编程技术网

Reactjs 反应+;Redux:处理调度后逻辑的正确方法

Reactjs 反应+;Redux:处理调度后逻辑的正确方法,reactjs,redux,Reactjs,Redux,我有一个具有某些内部状态(例如isLoading)的组件,可以访问redux数据。在这个组件中,我想发送一个thunk操作(api请求),导致redux数据更改。完成thunk后,我需要更改组件的状态。在我看来,有两种方法可以做到这一点: 使用thunk的promise return并在那里做我需要的一切,例如 将回调传递给thunk并从thunk本身启动它,例如 哪一种方法是正确的?更安全的方法是使用promise实现,因为您将确定该函数只有在promise得到解决后才会运行。第二个实现没有固

我有一个具有某些内部状态(例如isLoading)的组件,可以访问redux数据。在这个组件中,我想发送一个thunk操作(api请求),导致redux数据更改。完成thunk后,我需要更改组件的状态。在我看来,有两种方法可以做到这一点:

  • 使用thunk的promise return并在那里做我需要的一切,例如
  • 将回调传递给thunk并从thunk本身启动它,例如

  • 哪一种方法是正确的?

    更安全的方法是使用promise实现,因为您将确定该函数只有在promise得到解决后才会运行。第二个实现没有固有的缺陷,但是如果thunk中的任何内容是异步的,那么它将无法正常工作,因为它将在到达代码时运行,而不是在上面的代码完成执行时运行。当处理任何可以是异步的(服务器请求/加载数据/提交数据)时,使用Promise实现总是更安全的。

    可能是更新组件级状态或基于更改redux状态(或任何相关的道具/状态更改)运行回调函数的最佳实践要使用componentDidUpdate或useEffect:

    componentDidUpdate(prevProps, prevState){
         if(prevProps.someReduxState !== this.props.someReduxState && this.state.isLoading){
            setState({isLoading:false})
         }
    }
    
    useEffect(()=>{
        if(!props.someReduxState){
             setLoading(true)
        } else {
             setLoading(false)
        }
    },[props.someReduxState])
    
    有效期:

    componentDidUpdate(prevProps, prevState){
         if(prevProps.someReduxState !== this.props.someReduxState && this.state.isLoading){
            setState({isLoading:false})
         }
    }
    
    useEffect(()=>{
        if(!props.someReduxState){
             setLoading(true)
        } else {
             setLoading(false)
        }
    },[props.someReduxState])
    
    但是,我可能会推荐一种不同的方法(取决于目标,尤其是初始数据获取),用于管理redux中状态的加载:

    改为使用加载值初始化redux状态:

    export default someReduxState = (state = {notLoaded:true}, action) => {
        switch (action.type) {
            case actions.FETCH_SOME_REDUX_STATE:
                return action.payload;
            default:
                return state;
        }
    }
    
    然后,您可以在组件中检查:

    if (this.props.someReduxState.notLoaded ){
        // do something or return loading components
    } else {
        // do something else or return loaded components
    }
    

    这看起来更像是最糟糕的做法。如果状态存储在redux中,则在redux中处理它。它已经通过
    connect
    触发了重新加载程序,因此使用
    componentdiddupdate
    实际上是可怕的,而且没有必要的。我同意这就是为什么我将管理加载状态的“不同方法”放在redux中,而不是将isLoaded添加到组件级状态。但是,如果OP希望基于redux中的某些状态管理某些组件状态,那么我认为我的答案仍然是静态的。我编辑了我的答案,以便更清楚地说明我所说的最佳实践。我认为在redux中添加或跟踪加载是不可行的,使用本地状态管理它要容易得多。Redux状态更新和Reenders启动之间的时间几乎可以忽略不计。我同意在组件级别管理加载状态是有用的。答案的后一部分有助于在最初获取和发送数据时避免不必要的渲染。通过使用加载值(如
    {notLoaded:true}
    )初始化来管理加载状态(如果需要重新加载数据,在卸载时也可以将其重置为该值)关于使用承诺的第一种情况的问题:即使承诺得到履行,是否仍然存在redux状态尚未发送到组件的风险?不幸的是,我认为您永远无法保证您的组件将首先获得更新的redux状态。我假设一旦分派的操作完成,承诺就会得到解决,因此解决的函数将在组件中的redux状态更新之前运行。这实际上还取决于解析函数中的代码,因为JS是异步的。如果您确实需要确保在Redux状态发生更改后运行某些操作,您可以使用componentDidUpdate(prevProps)来比较prevProps和this.props,然后采取相应的行动。这也不重要,因为正如另一位评论者所说,一旦Redux状态更新,connect就会为组件触发Rerender。这实际上取决于您试图实现什么,您是在操作分派之后、在Redux状态更改之后还是在组件获得更新的Redux值之后尝试执行代码?第一个是通过thunk中的承诺实现的,第三个是通过componentDidUpdate实现的。第二个问题不重要,因为Redux状态与组件是分开的,你不需要关心它何时更新,只要它更新就行