【问题标题】:React/Redux: modified state is not updated in viewReact/Redux:修改后的状态未在视图中更新
【发布时间】:2016-05-15 17:04:16
【问题描述】:

在我使用 redux 的 react native 应用程序中,reducer 似乎工作正常,但 UI 不会在状态修改时更新。

这是我的减速器:

const initialState = {
  userId: 1,
  userName: "nobody",
  showIntroOnNextStart: true
}

export default function reducer(state = initialState, action) {

    switch(action.type) {
        case 'INCREMENT':
            let newState = {
                ...state,
                userId: state.userId + 1
            };
            console.log(newState);
            return newState;

    }
    return state;
}

它将通过以下方式导出和导入:

import userProfile from './userProfile'

export { userProfile }

这是我的连接方法:

export default connect(state => ({
   state: state.userProfile
 }),
 (dispatch) => ({
   actions: bindActionCreators(actions, dispatch)
 })
)(ApplicationContainer);

所以最终的状态是这样的:

在我的应用程序组件的渲染方法中,我将状态传递给子组件:

render() {
    const { state, actions } = this.props;
    return ....lots of scenes...
            <Scene key="home" component={HomeScreen} title="Home" state={state} {...actions} />

在特定的场景组件中,我使用这样的状态:

render(){
    const { state, decrement, increment } = this.props;

    return (
        <View {...this.props}  style={styles.container}>

            <Text>{state.userId}</Text>

            <Button onPress={increment}>Increment</Button>
        </View>
    );
}

增量操作按预期工作正常,每个 console.log-Output 都会显示一个具有正确增量值的新状态对象。

但视图不会更新。 在 reducer 函数中,状态按预期工作,并在每次调用时递增 userId。但在渲染函数中,状态对象的值从一开始就保持不变。

这里可能出了什么问题?

更新

当我从 react-native-router-flux 中删除这个 Router-Stuff 时,一切正常。状态将是相同的实例并将被更新。但是一旦将组件封装到路由器的场景中,状态更新就不会发生

【问题讨论】:

  • 你有没有试过console.log你传递给渲染函数的props?如果它没有像一个动作发生那样频繁地记录,可能是你定义了一个 shouldComponentUpdate 函数,它跳过了更新?
  • 只是一个评论;当您使用 state 作为 props 变量时,这会令人困惑。您应该尝试找到适合您设计的另一个名称。

标签: javascript reactjs react-native redux


【解决方案1】:

从我在 Redux 的有限时间来看,不渲染的问题通常是对象的引用没有改变。如果您有深层对象,则需要进行深层复制。我个人喜欢将 immutable.js 用于任何反应状态。

您可以尝试缩小问题范围的另一件事是在按增量后在组件上调用 this.forceUpdate()。如果它更新了视图,那将使您更接近找出问题所在。

【讨论】:

    【解决方案2】:

    更改状态不会立即更新它,它只会将其置于待处理状态。

    根据我的经验,它不会显示更新的原因是实际更新状态的智能组件和显示状态的哑组件之间存在断开连接。在大多数情况下,您应该让智能容器将应用程序状态传递给它们的组件:在这种情况下,您的应用程序组件会将递增的 id 传递给场景。我无法立即看到的是您的 handleOnPress 函数在哪里。理想情况下,您希望将状态和 onPress 函数都传递给您的场景,以便当他们单击它时,它会从您的应用容器调用操作,这将更新状态并触发重新渲染。

    希望这会有所帮助,我没有立即发现您在此处提供的代码有任何问题,但这可能与您将它们连接在一起的方式有关。

    【讨论】:

    • 当我从 react-native-router-flux 中删除这个 Router-Stuff 时,一切正常。状态将是相同的实例并将被更新。但是一旦将组件封装到路由器的场景中,状态更新就不会发生
    【解决方案3】:

    您是否在某个时候使用过导航器?我注意到 Navigator 创建了一次场景,即使之后数据发生了变化,即使状态更新,它也不一定会在挂载后重新创建场景。我的临时解决方案(在完全放弃导航器之前)是使用 this.forceUpdate()。这不是一个理想的解决方案,但可以完成工作。

    【讨论】:

    • 据我所知,使用的 redux-router-flux-component 使用新的 NavigatorExperimental
    • 在哪里放置 this.forceUpdate()?在渲染方法中?
    • 你可以试试这样的:
    【解决方案4】:

    你可以试试这个吗?告诉我结果...

    案例“增量”: 让 newState = Object.assign( {}, ...状态, 用户 ID:state.userId + 1 ); 控制台.log(newState); 返回新状态;

    【讨论】:

    • 这给出了一个语法错误:let newState = Object.assign( {}, ...state, userId: state.userId + 1 );
    • 啊,一定是: let newState = Object.assign( {}, ...state, {userId: state.userId + 1} );但它没有帮助。与bevore相同的行为
    • 嗯,而不是在您的特定场景组件中使用 const。你试过用let吗?也许它不会因为'const'而发生变异
    • 当我从 react-native-router-flux 中删除这个 Router-Stuff 时,一切正常。状态将是相同的实例并将被更新。但是一旦将组件封装到路由器的场景中,状态更新就不会发生
    • @adrianhartanto const 只防止重新分配
    【解决方案5】:

    您需要连接到 redux 存储,将状态映射到场景组件中的道具

    【讨论】:

      猜你喜欢
      • 2017-09-21
      • 2019-05-30
      • 2021-03-05
      • 2019-12-29
      • 2021-01-08
      • 2018-10-28
      • 1970-01-01
      • 2017-07-31
      • 1970-01-01
      相关资源
      最近更新 更多