We know that if we want to re-render a react component connected by react-redux, we should return a new array in reducer when we dispatch a related action. My problem is that why react component can re-render when redux reducer do not return a new array? When I click App component button, first app name becomes 'aaa', why???
actions:
export function setAppName(name: string) {
return {
type: 'SET_APP_NAME',
name,
}
}
reducers:
export function appInfos(state = {
appInfos: [
{name: 'ccc'},
{name: 'ddd'},
]
}, action: any) {
switch(action.type) {
case 'SET_APP_NAME':
// just return origin array, not a new array
const appInfos = state.appInfos;
appInfos[0].name = action.name
return Object.assign({}, state, { appInfos })
default:
return state;
}
}
component App:
function mapStateToProps(state: any) {
return {
app: state.appInfos
}
}
function App() {
const { app } = useSelector(mapStateToProps)
const dispatch = useDispatch()
const onClick = useCallback(() => {
dispatch(setAppName('aaa'))
}, [dispatch])
return (
<div className="app">
{app.appInfos.map((info: any) => {
return <div key={info.name}>{info.name}</div>
})}
<button onClick={onClick}>click</button>
</div>
);
}
container & store:
const store = createStore(combineReducers({
appInfos
}))
ReactDOM.render(
<Provider store={store}>
<React.StrictMode>
<App />
</React.StrictMode>
</Provider>,
document.getElementById('root')
);