【问题标题】:Redux/React - Search field is not updating the redux state instantlyRedux/React - 搜索字段不会立即更新 redux 状态
【发布时间】:2016-07-14 22:46:03
【问题描述】:

我是 redux 世界的新手,我正在尝试制作报纸应用程序。我目前正在研究用户可以搜索特定报纸标题的搜索功能。问题是当我第一次输入例如'a'时,状态是''。当我输入更多例如'b'时,状态显示该术语是'a',而它应该是'ab'。我正在使用 redux chrome 工具来检查这个全局状态。

我的 Actioncreator 真的很简单(只返回传递给它的术语):

export function search(term) {
  return{
    type:SEARCH,
    term
  }
}

这里是减速器:

const SearchReducer = (state = '', action) => {

    switch (action.type) {
        case SEARCH:
            return action.term;
        default:
            return state;
    }

}

这是根减速器:

/*Application state*/
const rootReducer = combineReducers({
    weather: WeatherReducer,
    filters: FilterReducer,
    articles:ArticleReducer,
    search: SearchReducer // this should be 'ab', but is 'a' 
});

这是非常简单的设置。以下是我与 redux 沟通的方式。

我有自己的 material-ui 文本字段(我也尝试过香草输入字段)

<TextField  style={style.searchWidget.search}
            floatingLabelText="Search"
            value={this.state.term}
            onChange={this._onSearchChange}
 />

当用户输入内容时,_onSearchChange 函数被触发。

_onSearchChange(event) {
    this.setState({term: event.target.value});
    this.props.search(this.state.term);
}

这将设置此搜索组件的当前状态。然后它将分派搜索操作,该操作将更新全局状态。但不能正常工作。全局状态总是落后 1 步。

有什么想法吗?

编辑: 看起来它不是redux而是react。组件状态不会立即更新。正确的术语被传递给 actionreducer,所以这不是 redux 的错。我试图在设置状态后打印出 this.state.term 。而且状态似乎没有更新。

【问题讨论】:

    标签: search reactjs state redux


    【解决方案1】:

    这个答案对Aniket Nandan 指出的内容有所补充——您在 React 组件内部使用 setState 而不是依赖于上面的道具。

    使用 Redux 的主要目的是获取您的状态并将其放入应用程序旁边的容器中。这样做的好处是您的状态可以在多个组件之间共享,然后您可以通过 props 将内容传递到组件树中的组件中。

    使用状态容器(它总是让我想起一些使用状态机)允许您构建应用程序,而无需通过树向下传递回调以获取更改以返回顶部的复杂性.取而代之的是,Redux 处理状态的变化,并通过 props 将所有内容交还给 React。

    _onSearchChange(event) {
        this.setState({term: event.target.value});
        this.props.search(this.state.term);
    }
    

    在那张纸条上,从您的帖子中查看上面的代码,我想知道为什么您将状态设置为该术语,但总是调用您通过道具收到的函数?然后搜索是否会从 Redux 存储中调用 dispatch 方法?如果没有,那么你的接线不正确。

    更进一步,如果您正确使用了connect(来自react-redux),那么您应该可以使用来自 Redux 存储的调度方法(这通过上下文发生)。

    Redux 设计的工作方式更像是这样:

    _onSearchChange(event) {
        this.props.dispatch({ type: 'SEARCH', term: event.target.value });
    }
    

    然后会发生的是 Redux 应该处理状态更新,并且新状态将通过 props 从 Redux 流向 React(这通过 Redux 中的所有连接发生,这非常棒!)。

    const SearchReducer = (state = '', action) => {
    
        switch (action.type) {
            case SEARCH:
                return action.term;
                break;
            default:
                return state;
        }
    
    }
    

    根据您的 reducer(复制到上面 ^^)和您对 combineReducers 的使用,如果您输入了“ab”,您最终应该会得到一个具有 { search: { term: 'ab' } } 的状态,并且在仅输入后它应该是“a” 'a',而不是落后。

    您使用setState 和来自道具的方法实际发生的情况是初始状态(我假设'')第一次被传递给this.props.search。同时,在您输入“a”后,组件的状态正在更新为'a'。然后,下一次,当您键入“b”时,状态正在更新为“ab”,但this.props.search 只是在setState 完成执行之前从状态接收到术语——而它仍然是“a”。

    这实际上是 Redux 如此出色的原因之一——它提供了一种方法来确保根据用户在其自己的容器中的操作正确更新状态,这样您就可以保证在您的应用程序中保持同步。

    关于这一点,我将留下一条关于使用 Redux 的建议:您应该很少发现自己在使用 Redux 的应用程序中的 React 组件中使用 setState。何时在组件中使用setState 的决定应取决于您要设置的状态是否仅存在于该组件中,而应用程序的其余部分不需要知道它。我想不出一个例子,我能提供的任何例子都可能是相当做作的。就这一点而言,我想不出一个的原因是因为我认为在应用程序中会有这样的用例是非常罕见的。

    因此,您应该坚持只使用 Redux 存储中的 dispatch 方法,并允许 Redux 通过其工作流程处理状态更新,并允许状态通过 props 向下流动到组件。遵守此流程将防止许多可能发生的这些奇怪的“状态不同步”类型的问题。

    【讨论】:

      【解决方案2】:

      其实和redux没有关系。在使用 react 时,您必须记住,一旦更新您的反应状态,您就无法获得更新的状态。举个例子吧。

      getInitialState: function() {
        return {
           myState: 0
        }
      },
      
      updateState: function(stateVersion) {
         console.log(this.state.myState); //this will print 0
         this.setState({ myState: stateVersion });
         console.log(this.state.myState); //this will print 0
      }
      

      现在,如果我们第一次使用状态版本作为参数调用 updateState 函数,即使我们发送 1 或 2 或任何数字作为参数,它也会为控制台打印 0。 假设我们发送了 2 作为参数。然后我们可以在该函数的下一次调用中使用另一个参数获得该状态。 但是 react 也照顾到了这一点。 您可能会认为,如果我们更新后状态没有更新,那么我该如何处理。但反应是一个好孩子...... 如果你调用一个函数来更新一个状态,然后你调用另一个函数来处理最后更新的状态,那么你可以使用它。

      我想我已经回答了你为什么不更新 redux 状态的问题。

      另一个想法是,当您使用 redux 状态作为搜索减速器时,为什么还要处理反应状态。您可以直接将搜索到的参数传递到您的操作中。您可以从减速器状态立即获取该更新。 它将帮助您简化代码。

      【讨论】:

        【解决方案3】:

        我找到了解决方案。 React - State not updated 看来 setState 实际上并没有立即设置状态。 所以我改用了回调函数。

            _onSearchChange(event) {
            this.setState({term: event.target.value}, function () {
                console.log(this.state.term)
            });
            }
        

        现在当我输入“a”时,它会记录“a”!

        【讨论】:

        • 在这种方法上,我仍然建议您确保使用“调度操作”方法,因为您使用的是 Redux。但是,如果您使用状态来设置输入(您似乎正在这样做?),那么请确保您允许新道具在它们从上方下降时覆盖该更改。这让我觉得有点像“乐观渲染/更新”。因此,如果您使用 state 来设置输入 - 请确保您有办法在 newProps 从 Redux 流中进入时更新组件本地的 state。
        • 但是,如果您不使用状态来设置输入,那么您可能会从在 setState 中使用回调而只使用来自 Redux 存储的调度(正如我提到的在我上面的回答中)。本周早些时候,我在setState 上回答了一个关于为什么/何时使用回调选项的问题(当面,而不是在 SO 上)。在解释了方法触发的顺序以及实际调用回调的时间之后,我总结说:“使用 Redux 通常会消除对诸如在 setState 调用中添加回调等变通方法的需要。”跨度>
        猜你喜欢
        • 2021-11-07
        • 1970-01-01
        • 2017-12-07
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2021-10-17
        • 1970-01-01
        相关资源
        最近更新 更多