Use Redux with Render Props

Kent C. Dodds
InstructorKent C. Dodds

Share this video with your friends

Send Tweet
Published 5 years ago
Updated 3 years ago

Now that we have everything wired up to share and update the state of the toggled boolean across our application, let's see how easy it would be to change from the state of a single boolean to state in a redux store! We’ll call it rendex (render props + redux). 😍

Instructor: [00:00] As fun as it is to update the state of a Boolean, that is controlled throughout our entire application using this cool provider and our connected toggle thing. It even reaches through shoot component update is false. That's a pretty cool accomplishment, but it's only one Boolean.

[00:17] What if we could store our entire application state in this way? The de facto for storing application state is Redux. We're going to create rindex with this toggle provider, and the connected toggle, and out toggle component. We'll switch it over to a rindex component.

[00:35] The first thing we need to do is add Redux to our page. Let's go ahead and add a script tag for Redux. Then I'm going to take every instance of toggle on the page, and replace it with rindex. We'll do the same thing for our lowercase t toggle with rindex. Let's begin our refactor.

[00:56] Instead of default on, we're going to have initial state. That's going to default as an object. Our initial state is going to come from this.props.initialState. We're going to change from onRindex to onUpdate. Then let's create our store.

[01:12] We'll say store=redux.createStore. We're going to create our own root reducer. We'll initialize it with our initial state. Our root reducer is going to be a function that takes state and an action, and returns this.props.reducer, state, and action. Just for the fun of it, we'll make reducer, e, a function that takes state and returns state.

[01:39] Let's update the reset. Instead of isOnControlled, we'll change this to isStatecontrolled. Instead of this.props.on, we'll say state on our props, here and here, and then in the case that our state is controlled, we'll just call this.props.onReset with this.initialState.

[02:00] If it's not controlled, then we'll call this.store.dispatch, with a special action with a type rindexReset, and we'll get rid of this setState stuff. Then in our root reducer, we'll handle that. We'll say if the action type is rindexReset, then we will return this.initialState.

[02:23] Luckily for us, we don't need this toggle function, which is now rindex, or get rindex or props. We don't need those anymore. We have a mechanism for updating the state, and that's dispatch.

[02:35] One thing we do need is a componentDidMount. When the component mounts, we need to subscribe. We'll say this.store.subscribe, and every time there's an update, we'll say this.setState, with this.store.getState.

[02:51] We don't want a memory leak, so we'll say this.unsubscribe equals the result of calling that function. Then we'll say componentWillUnmount, and call this.unsubscribe.

[03:02] Our render function is going to be a little bit different. We don't need these things anymore. We do want that reset, and we're definitely going to want a dispatch is .store.dispatch. The state is what we want. Instead of the onState, we'll just get the regular state. We'll get it from props if it's controlled, and if it's not, then we'll get it from the store.

[03:23] Let's update our rindex provider. It's rendering the rindex component, accepts a rindex object, and that is the value for react-broadcast. Our connected rindex is going to subscribe to our rindex provider's channel. It accepts a rindex, and renders with the rindex.

[03:41] Then we have the withRindex higher-order component. It renders a connected rindex, and that render prop accepts a rindex, and renders the component with rindex. Our update blocker remains unchanged.

[03:53] My input now uses connected rindex with the render prop, and instead of on, we're actually going to just accept rindex. Rindex is going to have our state, and we'll set that up in our Redux store here in a little bit.

[04:08] Instead of rindex, we're going to call rindex.dispatch. We'll make a type toggle and the value of true and false. In my switch, instead of getting on here, we'll get rindex.state.on. We'll say rindex.dispatch, with the type of toggle, and the value of notRindex.state.on.

[04:36] Our state printer, we'll get rindex, and it'll print out rindex.state. Our app uses the rindex provider. We don't need default on. We now need initial state, which will initialize to on is true. Let's see what we broke.

[04:52] Of course, we have a syntax error, and I knew I needed an extra parenthesis. We're getting an issue with getting state from undefined. That's because we're de-structuring rindex in my switch when rindex is the object that we get. Cool.

[05:06] Looks like state is now getting updated. That's because we don't yet have a reducer that handles actions of these types. Let's create our reducer.

[05:15] Reducer equals a function that takes state and action, and returns the state. We'll make a switch statement here, with action.type, and if it's toggle, then we'll return an object with the state, and on is going to be action.value. Otherwise, with the default case, we'll return the state. Now, I can toggle that on and off.

[05:43] For fun, let's add another case in our reducer input change. This will return our state, and input value will be action.value. We'll use this action type in our input at the bottom here. We'll say rindex.dispatch type input change, and the value is event.target.value.

[06:13] Now, "Hello, World!" and I could store anything in here that I like, using all the nice utilities from Redux. This was a pretty simple straight up refactor of a toggle component to a full-fledged Redux component.

[06:27] What this teaches us is that the patterns of render props, and state initializers, and controlled components, and the utility of react-broadcast are really powerful, and applicable in many scenarios, whether it be just a small, isolated component that you're going to reuse in multiple places, or a bigger component that controls state of the entire application.

Jarrod Payne
Jarrod Payne
~ 5 years ago

Kent,

I'm trying to compare / contrast this approach with a react-redux connected component. Do you have any insight to offer here?

Kent C. Dodds
Kent C. Doddsinstructor
~ 5 years ago

Hi Jarrod, This lesson was purely for instruction. There are already several implementations of a render-prop version of react-redux. I've never tried them before, so I can't tell you whether they're any good. And to be perfectly honest I'm not huge on redux (despite using it in a few apps). So I'm not the right person to give you advice here. I recommend you try both and see which you like best :)

Good luck!

Jarrod Payne
Jarrod Payne
~ 5 years ago

Thanks Kent. Great course, btw. I'm really enjoying it.

James Talmage
James Talmage
~ 5 years ago

And to be perfectly honest I'm not huge on redux

Why not?

James Talmage
James Talmage
~ 5 years ago

And to be perfectly honest I'm not huge on redux

Why not?

Kent C. Dodds
Kent C. Doddsinstructor
~ 5 years ago

Hi James!

Subscribe to this issue on my AMA to be notified when I have time to answer it :) https://github.com/kentcdodds/ama/issues/340

Redd
Redd
~ 4 years ago

Said rendux so many times :'D. Loved the course.

Michael Carter
Michael Carter
~ 4 years ago

Great lessons overall.

One request. It would be nice if you could present the initial version of the code (either on GitHub or in the code section) before you start your refactor, especially if it's not a continuation of the previous lesson.

I like to make the modifications to the source as I watch the lesson. I feel that if I physically type in the new code, it helps me retain the information faster. Most of the time I will try to make the change before I watch your version to see if I'm truly understanding the material.

For now, I'm scrubbing through the video to see the initial code so I can type that in (and make sure it's working) before I start the lesson. This would just save me some time.

Thanks again for the awesome course. I've been reading a lot of articles, so I knew a lot of the material already, but these quick, targeted lessons really helped solidify the knowledge.

Kent C. Dodds
Kent C. Doddsinstructor
~ 4 years ago

Thanks for the feedback Michael. That's a good point. When I update this course (soon), I'll be using this repo: https://github.com/kentcdodds/advanced-react-patterns-v2 That has the exercise and the final version. I think you'll appreciate that :)

kvrmd
kvrmd
~ 4 years ago

Thanks for the feedback Michael. That's a good point. When I update this course (soon), I'll be using this repo: https://github.com/kentcdodds/advanced-react-patterns-v2 That has the exercise and the final version. I think you'll appreciate that :)

Looking forward to it!

Mickey
Mickey
~ 4 years ago

Hello Kent, overall the course was great thanks and have certainly learnt some new stuff.

However in a couple of lessons, I found the pace was too quick to keep up with. (Specifically the Implement React Context Provider, and the Use Redux with Render Props). I would suggest keeping the lesson at a pace which allows the concepts to be taken in. I know time is important, but then maybe have a more contrived lesson.