在React Redux中更新嵌套对象的字段,而不是重新渲染视图(UI)

sauutmhj  于 11个月前  发布在  React
关注(0)|答案(2)|浏览(157)

我正在开发一个使用React和Redux作为前端JavaScript框架的Web应用程序。我在渲染视图和更新Redux状态/存储值方面遇到了一些问题。
我有一个更新Redux状态值的输入字段。这是我的文本字段的onChange的事件处理程序。

_handleNameInput= (event) => {
     this.props.updateField({
             name: 'name',
             value: event.target.value,
     })
}

字符串
在reducer中,我像这样更新状态字段

case RESTAURANT_CATEGORY_UPDATE_FIELD: {
            let freshState = { ...state };
            _.set(freshState, action.payload.name, action.payload.value);
            return freshState;
        }


我使用Lodash来更新state对象的字段。
这是我的默认状态

let defaultState = {
     name: ''
}


当用户输入时,我在视图上显示live state值,如下所示。

<h1>Name is: {this.props.name}</h1>


上面的场景工作得很好。当我改变输入的值时,它也显示了实时更改。当我在状态中使用嵌套对象时,问题就开始了。我更新了defaultState。

let defaultState = {
     form: {
        name: '',
     }
}


然后在回调中,我像这样更新。

this.props.updateField({
      name: 'form.name',
      value: event.target.value,
})


它正在更新对象的嵌套属性的redux状态/存储值。

<h1>{this.props.form.name}</h1>


它没有更新/呈现视图。我如何修复它?

jobtbby3

jobtbby31#

当你通过connect函数将你的组件连接到redux时,你的组件表现得像一个PureComponent。也就是说,它将对新的props进行浅层检查,将它们与以前的props进行比较,看看组件是否应该执行更新。
在第一个示例中,name是一个顶级属性,它的变化被检测到,所以更新被执行。
在第二个示例中,form是没有更改的顶级属性,因此阻止了更新。
正如注解中所建议的,您可以使用immer来确保form对象被替换为具有更新的name属性的新对象。

import produce from "immer";

return produce(state, draft => {
  _.set(draft, action.payload.name, action.payload.value);
});

字符串
在第二种情况下,它将有效地做到以下几点。

return {
  ...state,
  form: {
    ...state.form,
    name: action.payload.value
  }
};


不过我建议你重新考虑使用一个action和reducer来更新任意深度嵌套的字段,而是使用一些更具体的东西。
RESTAURANT_CATEGORY_UPDATE_FORM_FIELD

return {
  ...state,
  form: {
    ...state.form,
    [action.payload.name]: action.payload.value
  }
};


return produce(state, draft => {
  draft.form[action.payload.name] = action.payload.value;
});

8fsztsew

8fsztsew2#

只是因为我正在浏览这个immer的东西看起来很酷,但你也可以只设置一个属性关闭和关闭在你的状态的浅端

state.something.somethingelse = {
          ...state.something.somethingelse,
          updatedItem: posts,
          forceReRender: !state.something.somethingelse.forceReRender
        };

字符串

state.forceRender = !state.forceRender

相关问题