Why React component props is not updated when you change the vault Redux in another component?

Hello!
Began to study Redux to React. Immediately faced with the problem of shared data across components. Here is an example of code that doesn't work for me:
Initially, there is a file index.js where you created the vault redux and transmitted through the Provider in all components:
<Provider store={this.state.store}>
 <Header />
 The <Body />
 //Here is more other components
</Provider>

Further, in the component Header I'm trying the render method to get the current state of the props:
class Header extends React.Component {
 render() {
console.log(JSON.stringify(this.props.store));
 return (");
}
}
export default connect(
 store => ({
 store: store
})
)(Header);

But the console displays only the initial state of the repository, not the one I asked in another component. If the store status update from another component in another component you can see the storage upgrade, and Header are still the old initial data.

This example updates the repository from another component:
class Body extends React.Component {
 componentDidMount() {
 setTimeout(() => {
updateStore(1);
});
}
 render() {
console.log(JSON.stringify(this.props.store));
 return (");
}
}

export default connect(
 store => ({
 store: store
}),
 dispatch => ({
 updateStore: (i) => {
 dispatch({type: 'new', store: i});
}
})
)(Body);

I believe the error is something trivial.

Thanks in advance.
March 23rd 20 at 19:40
4 answers
March 23rd 20 at 19:42
Solution
Thank you. But the decision was that reducer'e to return a new state object and not the old one, which passed in function arguments. Reducer and I'm still not published.
Just in case here is the WRONG section of CODE:
function reducer(state = initialState, action) {
 if (action.type === 'new') {
 state.playload = action.playload;
}
 return state;
}
const store = createStore(reducer);


It should be like this:
function reducer(state = initialState, action) {
 if (action.type === 'new') {
 return Object.assign({}, state, {
 playload: action.playload
})
}
 return state;
}
const store = createStore(reducer);

Roughly speaking, every time you need to return not the state which were transferred to the reducer and the new. If we are not talking about primitives, what pointed out in the comments.
Thank you all for the answers.
So there you have just a typo:
function reducer(state = initialState, action) {
 if (action.type === 'new') {
 store= action.store; // <---- WTF is store?
}
 return state;
}

const store = createStore(reducer);

In the review you sent this reducer without a typo.

In your particular case, the state is primitive, not an object. Primitives are copied by value, not by reference like objects, so all that you have written is not right for your particular case.
If you remove from reducer a typo, even if you state was the object, then you would still return a new object and components would correctly respond to the updates.
function reducer(state = initialState, action) {
 if (action.type === 'new') {
 state = action.store; // state now references a new object
}
 return state;
}
const store = createStore(reducer);


It is advisable to read:
1. Objects: pass-by-reference
2 Immutable update patterns - Claudia20 commented on March 23rd 20 at 19:45
Sorry. Before publishing the code, simplify it so it was nice to read people and not to create unnecessary issues. In my state the code was not primitive but was an object. The primitives you said, fixed my answer. - Chyna.Pfeffer66 commented on March 23rd 20 at 19:48
March 23rd 20 at 19:44
As far as I remember there should be additional the connect function which is called when changing state to mutate the props inside the component. Sho here it is not visible.
March 23rd 20 at 19:46
and where you store created? what are you in the provider put?
In the store here it is:
function reducer(store = initialState, action) {
 if (action.type === 'new') {
 store= action.store;
}
 return store;
}
const store = createStore(reducer);
- Chyna.Pfeffer66 commented on March 23rd 20 at 19:49
@Chyna.Pfeffer66,
const reducer = (state = initialState, action) => {
switch(action.type){
 case 'NEW':
 return {
...state
 state : action.payload
};
 default: 
 return state;
};
};


teach courses standards.. pass.. the code is horrible - brandon.Franecki0 commented on March 23rd 20 at 19:52
reducer adopts state i action - brandon.Franecki0 commented on March 23rd 20 at 19:55
March 23rd 20 at 19:48
Hard to say, since you provided the examples either unreliable or non-working code:
componentDidMount() {
 setTimeout(() => {
 updateStore(1); // <--- WTF?
});
}


Here is fully working example code that reproduces the logic of your:
import React { useRef, useCallback } from 'react';
import ReactDOM from 'react-dom';
import { Provider, connect } from 'react-redux';
import { createStore } from 'redux';

const UPDATE = 'UPDATE';

const update = (payload) => ({
 type: UPDATE
payload,
});

const reducer = (state = 0, action) => {
 if (action.type === UPDATE) {
 return action.payload;
}
 return state;
}

const store = createStore(reducer);

const mapStateToProps = state => ({ state });

const mapDispatchToProps = { update };

const Header = ({ state }) => (
 the <div>Header. State: {state}</div>
);

const ConnectedHeader = connect(mapStateToProps)(Header);

const Body = ({ state update }) => {
 const inputEl = useRef(null);
 const handler = useCallback(() => {
update(inputEl.current.value);
 }, [inputEl, update]);

 return (
the <div>
 the <div>Body. State: {state}</div>
 <input type="number" ref={inputEl} />
 <button onClick={handler}>Update state</button>
</div>
);
}

const ConnectedBody = connect(
mapStateToProps,
mapDispatchToProps,
)(Body);

const App = () => (
 <Provider store={store}>
 <ConnectedHeader />
 <ConnectedBody />
</Provider>
);

const rootElement = document.getElementById("root");
ReactDOM.render(<App />, rootElement);

Demo

Find more questions by tags ReduxReactJavaScript