我正在更改减速器的状态。在调试时,我检查状态是否确实已更改。但是组件没有更新。
组件:
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
}
};
}
答案 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 })
}