I would like to use redux to store the state of my whole react application, however I am stuck with a particular case:
componentDidUpdate
or componentDidMount
?Example of a react component to contain "cards" arranged by isotope layout library:
componentDidMount() {
let container = ReactDOM.findDOMNode(this);
if (! this.state.isotope) {
this.setState({ isotope: new Isotope(container, {itemSelector: '.grid-item', layoutMode: 'masonry'})});
}
}
componentDidUpdate(new_props, new_state) {
if (new_state.items_list != this.state.items_list) {
if (this.state.isotope) {
this.state.isotope.reloadItems();
this.state.isotope.layout();
this.state.isotope.arrange();
}
}
}
Is there a way to remove the local state in this component and to use redux instead ? I can't see how to do it
Put your items_list in your redux state. Your reducer might look like this:
const initialState = {
items: []
};
export function myReducer(state = initialState, action) {
switch (action.type) {
case 'SET_ITEMS':
return Object.assign({}, state, {
items: action.items
});
}
return state;
}
Or for something a little more complex:
const initialState = {
items: []
};
export function myReducer(state = initialState, action) {
switch (action.type) {
case 'ADD_ITEM':
return Object.assign({}, state, {
items: [ ...state.items, action.item ]
});
case 'REMOVE_ITEM':
return Object.assign({}, state, {
items: [
...state.items.slice(0, action.index),
...state.items.slice(action.index + 1)
]
});
}
return state;
}
Once you've configured your store and Provider (see the Redux docs), set up your "smart component" like so:
function mapStateToProps(state) {
return {
items: state.items
}
}
function mapDispatchToProps(dispatch) {
const actions = bindActionCreators(actionCreators, dispatch);
return {
addItem: actions.addItem,
removeItem: actions.removeItem
};
}
export default connect(mapStateToProps, mapDispatchToProps)(Root);
Now your items and actions are props to your Root component. If your items live in a lower order component, simply pass them down the tree as props.
I hope that gives you the general idea. With Redux what you'll find that your React components will use state a lot less and props a lot more.
One more thing...
This might be a minor matter, but I urge you NOT to store your isotope object on the component state. (Regardless of whether or not you use Redux.) The isotope object isn't really a piece of state, it's your view. In React, a component updates in response to a change in state. But your componentDidUpdate
does the reverse: it changes the state in response to a component update.
As an alternative, simply store it on the object itself. i.e.
componentDidMount() {
const container = ReactDOM.findDOMNode(this);
this.isotope = new Isotope(container, {
itemSelector: '.grid-item',
layoutMode: 'masonry'
});
}
componentDidUpdate(prevProps, prevState) {
if (prevProps.items !== this.props.items) {
this.isotope.reloadItems();
this.isotope.layout();
this.isotope.arrange();
}
}
(Whilst normally I would recommend against against using these sort of instance variables in React, DOM manipulation libraries like Isotope are a worthy exception.)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With