React and Redux Use Provider to Connect Redux to React
React and Redux Use Provider to Connect Redux to React

In this video you will learn how to start using Redux in React.
Let's jump right into it.

In previous video we build the Redux example in plain JavaScript to understand the core features of Redux. If you didn't watch that video or you don't know what dispatch, subscribe, getState from Redux are working I highly recommend you to watch that video first.

So our goal in this video is to build a Redux example in React world. We want to have a list of users and an input with the button so we can add new users to the list.


Here I have a generated create-react-app application. If you don't know how to generate it or what is it at all I already made a video on that.


Our first step to start using Redux inside React is to install react-redux package. What is this? It's a package for React that makes bindings to Redux. Which means we can use React with Redux easier. We also need to install Redux.

yarn add redux
yarn add react-redux

Now we need to create store in the same way like we did in our javascript example.

index.js

import { createStore } from "redux";

const store = createStore();

As you can see we are getting the error that we need to provide a reducer inside. Let's create a reducer.js file and put an action here. Just to remind you action is what we dispatch from our store in order to somehow change the state.

const reducer = (state = [], action) => {
  return state;
};

export default reducer;

Now we can pass it in our createStore.

import reducer from "./reducer";

const store = createStore(reducer);

The next this that we need to do is to wrap all our components in the Provider component which react-redux is giving us.

import { Provider } from "react-redux";
...
ReactDOM.render(
  <React.StrictMode>
    <Provider store={store}>
      <App />
    </Provider>
  </React.StrictMode>,
  document.getElementById("root")
);

So We wrapped our whole application in Provider and passed our store inside. Now the question is why we are doing this? So we want that every our component has access to the store. In React world this can be achieved by using React context. It's a way to create some global data or functions and they will be available in all components which are inside a Provider. As you can see we are passing our store inside exactly to make it available in all our components.


So let's move our markup to render users in our App component.

import { Component } from "react";

class App extends Component {
  state = {
    username: "",
  };

  handleUser = (e) => {
    this.setState({ username: e.target.value });
  };

  addUser = () => {
    console.log("addUser", this.state.username);
  };

  render() {
    return (
      <div>
        <input
          type="text"
          value={this.state.username}
          onChange={this.handleUser}
        />
        <button onClick={this.addUser}>Add user</button>
        <ul></ul>
      </div>
    );
  }
}

export default App;

So here we created a React class because we need a state for our input. So we adding input change and addUser function. As you can see everything is working and it is plain javascript.


Now how we can use Redux here?

We need to use connect function from react-redux. It's our single way to work with Redux from every component. As you can see we wrap our component in connect and provide inside as a first parameter mapStateToProps function. What is it? It's a way to describe what fields we want to get from Redux.
So first of all we want to read user data from our store.

import { connect } from "react-redux";
...
const mapStateToProps = (state) => {
  console.log("state", state);
  return {
    users: state,
  };
};

export default connect(mapStateToProps)(App);

As a first parameter we get our state. It's exactly what we got previously with store.getState. The only important thing here is to return an object back. Because the idea is that we want to read some data from state and make them available in our component. In this case we returned our users which is actually the whole state. But of course later we can have hundrends fields inside our state.

Now if we console.log props in our App component you can see that we get users property from connect inside.

  render() {
    console.log("props", this.props);
    ...
  }

Let's render our users.

<ul>
  {this.props.users.map((user, index) => (
    <li key={index}>{user}</li>
  ))}
</ul>

To test that it's working we can change the initial array that we have.


Now actually we want to dispatch our changes like we did previously. As you saw when we logged props we got there also dispatch function because connect gives it for us out of the box. Let's use it inside addUser.

addUser = () => {
  console.log("addUser", this.state.username);
  this.props.dispatch({ type: "ADD_USER", payload: this.state.username });
};

Now we need to update our reducer in our to change the state after ADD_USER action.

const reducer = (state = [], action) => {
  if (action.type === "ADD_USER") {
    return [...state, action.payload];
  }

  return state;
};

export default reducer;

As you can see everything is working and we are using Redux inside React now. The most important that you understand that there is no magic in redux or react-redux. Redux is a library with less that 50 lines of code and react-redux is just bindings for React with lots of sugar and performance optimisations.

Also if you want to improve your programming skill I have lots of full courses regarding different web technologies.

📚 Source code of what we've done