Redux vs. React New Context API

Taley'a Mirza

Taleymirza TaleyaMirza TaleyaMirza

Who am I?

What is Redux????

State Management Tool

const UserAvatar = ({ user, size }) => (
  <img
    className={`user-avatar ${size || ""}`}
    alt="user avatar"
    src={user.avatar}
  />
);
const UserStats = ({ user }) => (
  <div className="user-stats">
    <div>
      <UserAvatar user={user} />
      {user.name}
    </div>
    <div className="stats">
      <div>{user.followers} Followers</div>
      <div>Following {user.following}</div>
    </div>
  </div>
);
const Nav = ({ user }) => (
  <div className="nav">
    <UserAvatar user={user} size="small" />
  </div>
);
const Content = () =>
<div className="content">main content here</div>;
const Sidebar = ({ user }) => (
  <div className="sidebar">
    <UserStats user={user} />
  </div>
);
const Body = ({ user }) => (
  <div className="body">
    <Sidebar user={user} />
    <Content />
  </div>
);
class App extends React.Component {
  state = {
    user: {
      avatar:
        "https://www.gravatar.com/avatar/5c3dd2d257ff0e14dbd2583485dbd44b",
      name: "Dave",
      followers: 1234,
      following: 123
    }
  };

  render() {
    const { user } = this.state;

    return (
      <div className="app">
        <Nav user={user} />
        <Body user={user} />
      </div>
    );
  }
}

Why we use Redux in React? 

As Pete Hunt, one of the early contributors to React, says:

 

You'll know when you need Flux. If you aren't sure if you need it, you don't need it.

 

Similarly, Dan Abramov, one of the creators of Redux, says:

 

I would like to amend this: don't use Redux until you have problems with vanilla React.

When did a certain slice of state change, and where did the data come from?

(with predictable behavior)

  • store your whole application's state as plain data
  • describe changes as plain objects
  • handle those changes with pure functions that apply updates immutably

 

Three Principles of Redux


const initialState = {};
function reducer(state = initialState, action) {
  switch (action.type) {
    // Respond to the SET_USER action and update
    // the state accordingly
    case "SET_USER":
      return {
        ...state,
        user: action.user
      };
    default:
      return state;
  }
}

Create a reducer with an empty initial state


const store = createStore(reducer);

Create the store with the reducer


// (since initial state is empty)
store.dispatch({
  type: "SET_USER",
  user: {
    avatar: "https://www.gravatar.com/avatar/5c3dd2d257ff0e14dbd2583485dbd44b",
    name: "Dave",
    followers: 1234,
    following: 123
  }
});

Dispatch an action to set the user


const mapStateToProps = state => ({
  user: state.user
});

This mapStateToProps function extracts a single key from state (user) and passes it as the `user` prop

const UserAvatar = connect(mapStateToProps)(({ user, size }) => (
  <img
    className={`user-avatar ${size || ""}`}
    alt="user avatar"
    src={user.avatar}
  />
));

Connect() UserAvatar & UserStats

so it receives the `user` directly, without having to receive it from a component above

const UserStats = connect(mapStateToProps)(({ user }) => (
  <div className="user-stats">
    <div>
      <UserAvatar user={user} />
      {user.name}
    </div>
    <div className="stats">
      <div>{user.followers} Followers</div>
      <div>Following {user.following}</div>
    </div>
  </div>
));

both use the same mapStateToProps function


const Nav = () => (
  <div className="nav">
    <UserAvatar size="small" />
  </div>
);

const Body = () => (
  <div className="body">
    <Sidebar />
    <Content />
  </div>
);


const Sidebar = () => (
  <div className="sidebar">
    <UserStats />
  </div>
);

const Content = () => <div className="content">main content here</div>;

Nav, Sidebar and Body doesn't need to know about `user` anymore

 

const App = () => (
  <div className="app">
    <Nav />
    <Body />
  </div>
);

ReactDOM.render(
  <Provider store={store}>
    <App />
  </Provider>,
  document.querySelector("#root")
);

Wrap the whole app in Provider so that connect() has access to the store

What's New Context API??

The Context API is a first-class citizen in React

Is it New?

React 16.3 introduced a stable version of Context API

What is Context API for? 

Context is specifically intended for the use case of passing data to deeply nested React components.

React Context allows us to have a state that can be seen globally to the entire application via

  • The context provider (<Provider />)
  • The context consumer (<Consumer />)

const UserContext = React.createContext();

Create a Context

class App extends React.Component {
  state = {
    user: {
      avatar:
        "https://www.gravatar.com/avatar/5c3dd2d257ff0e14dbd2583485dbd44b",
      name: "Dave",
      followers: 1234,
      following: 123
    }
  };

  render() {
    return (
      <div className="app">
        <UserContext.Provider value={this.state.user}>
          <Nav />
          <Body />
        </UserContext.Provider>
      </div>
    );
  }
}

we pass the context down through the tree using the Provider

Components that need the data tap into the context by using its Consumer property

const UserAvatar = ({ size }) => (
  <UserContext.Consumer>
    {user => (
      <img
        className={`user-avatar ${size || ""}`}
        alt="user avatar"
        src={user.avatar}
      />
    )}
  </UserContext.Consumer>
);
const UserStats = () => (
  <UserContext.Consumer>
    {user => (
      <div className="user-stats">
        <div>
          <UserAvatar user={user} />
          {user.name}
        </div>
        <div className="stats">
          <div>{user.followers} Followers</div>
          <div>Following {user.following}</div>
        </div>
      </div>
    )}
  </UserContext.Consumer>
);

Should You Use Context, or Redux?

It depends..

  • code,
  • functionality,
  • scope,
  • coupling,
  • scalability

Screw driver vs. Impact Driver

Proclaims and Confusions

  • Redux is dead
  • Redux will be replaced by New Context API
  • What will be the future of Redux?

IF YOU ASK REDUX, HE WOULD PROBABLY SAY

The reports of my death are greatly exaggerated

- Mark Twain

TL;DR

Is Redux dead, dying, deprecated, or about to be replaced?

No.

Proclaims and Confusions

  • Redux is dead
  • Redux will be replaced by New Context API
  • What will be the future of Redux?

If you're only using Redux to avoid passing down props, context could replace Redux - but then you probably didn't need Redux in the first place.

Proclaims and Confusions

  • Redux is dead
  • Redux will be replaced by New Context API
  • What will be the future of Redux?

It's not just a library, it's an ecosystem

Best Resources

Taleymirza TaleyaMirza TaleyaMirza
Made with Slides.com