React updates the React component tree by comparing the reference of a state (Refer to Reconciliation).
In your case, updateProperty updates the property of the model, not the reference of myModel. Thus React thinks that there is no need to update the tree.
When using useReducer, you would usually dispatch an action, which is a Redux way of returning a new state.
And you can return a new reference return Object.assign({}, action.model, {property: action.property}); by returning a new object from the reducer (modelReducer).
Instead of using myModel directly, you use model returned from useReducer, which gets the new value from input.onChange.
functionmodelReducer(state,action){switch(action.type){case'UPDATE_PROPERTY':// return a new object referencereturnObject.assign({},action.model,{property:action.property});// if using ES9, which supports object spread// return {...action.model, property: action.property);default:returnstate;}}functionDontWork(){constmyModel=useModel()[0];const[model,dispatch]=useReducer(modelReducer,myModel);return(<div><h1>Nowworks</h1>
<inputonChange={e=>dispatch({type:'UPDATE_PROPERTY',model,property:e.target.value})}/><span>{model.property}</span>
</div>
)}
I've forked your initial fiddle and created a working version using the code above.
React updates the React component tree by comparing the reference of a state (Refer to Reconciliation).
In your case,
updateProperty
updates the property of the model, not the reference ofmyModel
. Thus React thinks that there is no need to update the tree.When using
useReducer
, you would usually dispatch an action, which is a Redux way of returning a new state.And you can return a new reference
return Object.assign({}, action.model, {property: action.property});
by returning a new object from the reducer (modelReducer
).Instead of using
myModel
directly, you usemodel
returned fromuseReducer
, which gets the new value frominput.onChange
.I've forked your initial fiddle and created a working version using the code above.
jsfiddle.net/dance2die/tw8759da/21/