Reputation: 2797
I set some values in React Redux store while the ComponentDidMount() function. Redux Dev Tools displays that the state has been updated. But in props
It doesn't get changed.
My reducer.js is,
const inititalState = {
slickColumns: null,
slickData: null
}
const reducer = (state = inititalState, actions) => {
switch(actions.type) {
case actionsTypes.SET_SLICK_GRID_COLUMNS: {
return {
...state,
slickColumns: columns
};
}
case actionsTypes.SET_SLICK_GRID_DATA: {
return {
...state,
slickData: [...mock_slick_data]
};
}
default: {
return state;
}
}
}
export default reducer;
action.js,
import * as actions from './actions';
export const setSlickGridColumns = () => {
return {
type:actions.SET_SLICK_GRID_COLUMNS
}
}
export const setSlickGridData = () => {
return {
type: actions.SET_SLICK_GRID_DATA
}
}
main.js, (Mapping Redux to state)
const mapStateToProps = state => {
return {
slickColumns: state.slickColumns,
slickData: state.slickData
};
};
const mapDispatchToProps = dispatch => {
return {
onSetSlickDataColumns: () => {
dispatch(actionTypes.setSlickGridColumns());
},
onSetSlickData: () => {
dispatch(actionTypes.setSlickGridData());
}
};
};
export default connect(mapStateToProps, mapDispatchToProps)(Dimensions()(Home));
in ComponentDidMount function,
this.props.onSetSlickDataColumns(); // able to see this method is running and the state is updated in Redux Dev Tools
this.props.onSetSlickData();
console.log(this.props.slickColumns); // getting null here.
dv.setItems(this.props.slickData);
Even thought the state is updated in store, I am still not able to get the data in the props? why? any ideas?
index.js,
import slickReducer from './store/reducers/SlickGrid';
const composeEnhancers = window.__REDUX_DEVTOOLS_EXTENSION_COMPOSE__ || compose;
const store = createStore(
slickReducer,
composeEnhancers(applyMiddleware(thunk))
);
const app = (
<Provider store={store}>
<BrowserRouter>
<App />
</BrowserRouter>
</Provider>
);
ReactDOM.render(app, document.getElementById("root"));
[Edit]: Initially I set initialState object properties as 'null;
Adding my Redux Screenshot here,
Adding extra some logs in here. This might helpful to resolve this issue. Actually the grid instance is created in ComponentDidMount()
method.
componentDidMount() {
console.log("[componentDidmount]....");
this.props.onSetSlickDataColumns();
this.props.onSetSlickData();
console.log(this.props);
if (this.props.slickColumns.length !== 0) {
const grid = (this.gridInstance = new Grid(
this.grid,
dv,
this.props.slickColumns,
options
));
// ------------------
}
}
When doing grid object, It should not have empty columns, and empty DataView.
I called the setSlickGridColumns
and setSlickGridData
method in various lifecycle methods such as constructor
, componentWillMount
and put console logs for props in mapStateToProps
, constructor
, componentWillMount
, render
and componentDidMount
methods also. From the logs what I am getting is,
[mapStateToProps]
this.props.slickColumns: null
[componentConstructor].... calling onSetSlickDataColumns() and onSetSlickData() methods here..
this.props.slickColumns: null
[componentwillmount].... calling onSetSlickDataColumns() and onSetSlickData() methods here..
this.props.slickColumns: null
[render]
this.props.slickColumns: null
[componentDidmount].... calling onSetSlickDataColumns() and onSetSlickData() methods here..
this.props.slickColumns: null
[mapStateToProps]
this.props.slickColumns: Array(300) // Here props values are set
[render]
this.props.slickColumns: Array(300)
From the logs, what I understand is, The data has to be filled before the componentDidMount
() method. But It doesn't setting up even though I dispatched reducer function in constructor
and ComponentWillMount
. Hope this logs help to resolve this problem.
Upvotes: 0
Views: 928
Reputation: 2595
Problem is you are not setting new data in your reducer you can see
const reducer = (state = inititalState, actions) => {
switch(actions.type) {
case actionsTypes.SET_SLICK_GRID_COLUMNS: {
return {
...state,
slickColumns : columns // you have to pass your new data as payload from your function : actions.payload
};
}
case actionsTypes.SET_SLICK_GRID_DATA: {
return {
...state,
slickData: [...mock_slick_data] // same here
};
}
default: {
return state;
}
}
}
You can pass your data when you dispatch an action
dispatch(actionTypes.setSlickGridColumns('Pass your data here '));
Then you can get your data as argument like
export const setSlickGridColumns = (data) => {
return {
type:actions.SET_SLICK_GRID_COLUMNS,
payload : data // pass your data as payload
}
}
Now you can use your data in reducer like actions.payload
.......
case actionsTypes.SET_SLICK_GRID_COLUMNS: {
return {
...state,
slickColumns : action.payload
};
........
Upvotes: 3
Reputation: 2648
Actually you're not going to get updated props in componentDidMount
lifecycle hook, as you are dispatching your function after your component is mounted. You'll get updated props in your render
, componentWillReceiveProps
(deprecated), getDerivedStateFromProps
and some other lifecycle hooks. You can read more about which lifecycle hooks are being called when props are updated in the official docs of react.
And then you're missing return statement in mapDispatchToProps as mentioned in one other answer.
Upvotes: 0
Reputation: 1507
try below code -> you need to return the dispatch inside the mapDispatchToProps like below
const mapDispatchToProps = dispatch => {
return {
onSetSlickDataColumns: () => {
return dispatch(actionTypes.setSlickGridColumns());
},
onSetSlickData: () => {
return dispatch(actionTypes.setSlickGridData());
}
};
};
Upvotes: 1