Props, State, Dispatch
I’m going to try to explain this a plainly as possible, not necessarily for you kind reader, but for me. If it helps someone in the future, awesome!
In short, there are essentially two ways to manage the data of your application: Props and State.
Basics: Props (Properties) are read only. Do NOT edit these. Passed INTO a component. Handled outside of the component. A great way to have dynamic variables so you don’t have to hard code it.
Basics: Handled/controlled by the local component. Do not mutate state directly. An update of state inside the component will cause a re-render of that component. Great to update values of state based on caused by a user.
Assign state in the constructor, and update state with setState().
The bad way is trying to assign something to this.state.ofSomeObject. We don’t like this because you could reassign the type (object{}, array[], or string””) leading to all sorts of chaos.
And here’s a beautiful thing about React: it will almost always tell you what’s wrong and/or what it wants! No techno-telepathly needed!
If the idea of state changing but not changing is hanging you up, perhaps consider it like this: state doesn’t want mutate, it just wants adapt. We update the state. I like to to think of it like this: let’s pretend our state is an empty object.
- State = {}
And within that object, you can have many things. Let’s have one of our many things be an empty array titled “pets”.
2. State = { pets: [] }
Now if we wanted to update the state of our pets with our fish, Nemo, we would add our new pet.
3. State = { pets: [“Nemo”] }
And finally, if we wanted to give Nemo to our neighbor, we’d update state again.
4. State = { pets: [] }
- Connect
Connect accepts arguments called anything! By convention though, we use (first) mapStateToProps, and (second) mapDispatchToProps. Yes, order matters! These could be named “mappingStateToProperties” or “iWouldLikeToMapMyDispatchActionsFromMyReducerToThePropertiesOfThisComponent”. Please don’t name your second argument something that long…
I always thought of this like “bringing in the state object and assigning it to the props for that component.
In the below example, we’re “connecting” and bringing in our state from the global Redux store, and assigning it to the props of the component. Cool thing is, you don’t have to bring in all parts of state! You can pick and choose.
So for “users” of the component, we’re assigning it from state.users. Now we can later pass in props to our functional component, and set specific variables within our component.
This the second half of connect(). With mapStateToProps coming in first, mapDispatchToProps is the second argument in connect. So keep in mind, if you don’t need mapStateToProps, connect still needs something in that spot, so fill it with null.
With mapDispatchToProps, and now you can create functions which are dispatched when called. These functions are passed as props to the component, which is why the name is called mapDispatchToProps. Map (gather) Dispatch (send) To (this function to) Props (props within the component.)
This second method is an easier way of coding the same thing:
Once you have connected your component in this way, your component receives props.dispatch
. You may use it to dispatch actions to the store.
Keep in mind, this isn’t “tunneling” into your reducers to call these functions. You’re bringing these functions INTO your component, allowing you to invoke them within this component. Really handy if you need to utilize a function in multiple places within your application because now you only need to write it once, and can freely invoke as needed. Similar to a partial in Ruby on Rails.