Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Subscribe to single property change in store in Redux

In Redux I can easily subscribe to store changes with

store.subscribe(() => my handler goes here) 

But what if my store is full of different objects and in a particular place in my app I want to subscribe to changes made only in a specific object in the store?

like image 746
karol.barkowski Avatar asked Mar 25 '16 01:03

karol.barkowski


People also ask

What is subscribe method in Redux?

In Redux, subscriptions are called after the root reducer has returned the new state, so you may dispatch in the subscription listeners. You are only disallowed to dispatch inside the reducers because they must have no side effects.

How does Redux update the store?

The only way to update a state inside a store is to dispatch an action and define a reducer function to perform tasks based on the given actions. Once dispatched, the action goes inside the reducer functions which performs the tasks and return the updated state to the store. This is what Redux is all about.

Should I keep all component's state in Redux store?

Some users prefer to keep every single piece of data in Redux, to maintain a fully serializable and controlled version of their application at all times. Others prefer to keep non-critical or UI state, such as “is this dropdown currently open”, inside a component's internal state. Using local component state is fine.


1 Answers

There is no way to subscribe to part of the store when using subscribe directly, but as the creator of Redux says himself - don't use subscribe directly! For the data flow of a Redux app to really work, you will want one component that wraps your entire app. This component will subscribe to your store. The rest of your components will be children to this wrapper component and will only get the parts of the state that they need.

If you are using Redux with React then there is good news - the official react-redux package takes care of this for you! It provides that wrapper component, called a <Provider />. You will then have at least one "smart component" that listens to state changes passed down by the Provider from the store. You can specify which parts of the state it should listen to, and those pieces of the state will be passed down as props to that component (and then of course, it can pass those down to its own children). You can specify that by using the connect() function on your "smart" component and using the mapStateToPropsfunction as a first parameter. To recap:

Wrap root component with Provider component that subscribes to store changes

ReactDOM.render(   <Provider store={store}>     <App />   </Provider>,   document.getElementById('root') ) 

Now any child of <App /> that is wrapped with connect() will be a "smart" component. You can pass in mapStateToProps to pick certain parts of the state and give it those as props.

const mapStateToProps = (state) => {     return {         somethingFromStore: state.somethingFromStore     } }  class ChildOfApp extends Component {     render() {         return <div>{this.props.somethingFromStore}</div>     } }  //wrap App in connect and pass in mapStateToProps export default connect(mapStateToProps)(ChildOfApp) 

Obviously <App /> can have many children and you can pick and choose which parts of the state the mapStateToProps should listen to for each of its children. I'd suggest reading the docs on usage with React to get a better understanding of this flow.

like image 83
Andy Noelker Avatar answered Sep 29 '22 02:09

Andy Noelker