在Reducer中更改存储后,useSelector不会更新。 ReactJS Redux

时间:2019-11-14 06:31:57

标签: javascript reactjs ecmascript-6 react-redux react-hooks

我正在更改减速器的状态。在调试时,我检查状态是否确实已更改。但是组件没有更新。

组件:

function Cliente(props) {
    const dispatch = useDispatch()
    const cliente = useSelector(({ erpCliente }) => erpCliente.cliente)
    const { form, handleChange, setForm } = useForm(null)

...

function searchCepChangeFields() {
    //This call the action and change the store on reducer
    dispatch(Actions.searchCep(form.Cep))  
        .then(() => {   
            // This function is only taking values ​​from the old state. 
            // The useSelector hook is not updating with store
            setForm(form => _.setIn({...form}, 'Endereco', cliente.data.Endereco))
            setForm(form => _.setIn({...form}, 'Uf', cliente.data.Uf))
            setForm(form => _.setIn({...form}, 'Cidade', cliente.data.Cidade))
            setForm(form => _.setIn({...form}, 'Bairro', cliente.data.Bairro))                  
        })
}

异径管:

 case Actions.SEARCH_CEP:
        {
            return {
                ...state,
                data: { 
                    ...state.data,
                    Endereco: action.payload.logradouro,
                    Bairro: action.payload.bairro,
                    UF: action.payload.uf,
                    Cidade: action.payload.cidade                    
                }
            };
        }  

2 个答案:

答案 0 :(得分:5)

在处理对象时,您面临的问题非常普遍, 道具不会改变,因为您正在更改对象的属性,但是对象本身不会从反应侧改变。

即使您给它一个全新的对象 react看不到属性对象更改,因为引用保持不变。

您需要创建一个像这样的新引用

 Object.assgin(state.data,data);

return {
           ...state,
           data: { 
               ...state.data,
               Endereco: action.payload.logradouro,
               Bairro: action.payload.bairro,
               UF: action.payload.uf,
               Cidade: action.payload.cidade                    
        }

要添加更多内容,您可以了解解决此问题的Immutable.js库。

答案 1 :(得分:1)

以某种方式,无法识别Object.assgin 使用ES6语法进行更新。

updatedConnectors = state.connectors

这将创建对当前状态的引用。在ES6中,引入了...作为新参考。

updatedConnectors = { ...state.connectors }
.....
return  {
    ...state,
    connectors: updatedConnectors
};

使用它来提取和复制新参考。那也会触发状态改变

更新Sep / 27/20 我已经编写了一些utils函数来处理此问题,让我们尝试一下

//Utils
export const getStateSection = ({ state, sectionName }) => {

  const updatedState = { ...state }
  const updatedSection = updatedState[sectionName]
  return updatedSection
}

export const mergeUpdatedSection = ({ state, sectionName, updatedValue }) => {
  const updatedState = { ...state }
  updatedState[sectionName] = updatedValue
  return updatedState
}

然后在任何减速器中,都应像这样使用:

//reducer
const initState = {
  scheduleDetail: null,
  timeSlots: null,
  planDetail: {
    timeSlots: [],
    modifedTimeSlots: [],
    id: 0
  }

}
.....  
const handlePickTimeSlot = (state, action) => {
  let planDetail = getStateSection({ state, sectionName: 'planDetail' })
  // do stuff update section
  return mergeUpdatedSection({ state, sectionName: 'planDetail', updatedValue: planDetail })
}