๐Ÿช† Nesting and overriding new React Context API

iamandrewluca

Andrei L

Posted on July 6, 2018

๐Ÿช† Nesting and overriding new React Context API

While learning react-router v4 I read some of their source code. And as we know they are using current context for passing down router and route info overriding previous/parent route info

GitHub logo remix-run / react-router

Declarative routing for React

Welcome to React Router ยท npm package build

React Router is a lightweight, fully-featured routing library for the React JavaScript library. React Router runs everywhere that React runs; on the web, on the server (using node.js), and on React Native.

If you're new to React Router, we recommend you start with the tutorial.

If you're migrating to v6 from v5 (or v4, which is the same as v5), check out the migration guide. If you're migrating from Reach Router, check out the migration guide for Reach Router. If you need to find the code for v5, it is on the v5 branch.

Documentation for v6 can be found on our website.

Contributing

There are many different ways to contribute to React Router's development. If you're interested, check out our contributing guidelines to learn how you can get involved.

Packages

This repository is a monorepo containing the following packages:

  • โ€ฆ

getChildContext() {
  return {
    router: {
      ...this.context.router,
      route: {
        location: this.props.location || this.context.router.route.location,
        match: this.state.match
      }
    }
  };
}
Enter fullscreen mode Exit fullscreen mode

React team announced new Context API that no longer will be deprecated in React v16.3.0, that is already released :)

https://github.com/facebook/react/releases/tag/v16.3.0

Now I was thinking how ReactTraining will make this overriding using new Context API.
From start I used create-react-context polyfill for new context. It works exactly, just change the import.

import { render } from "react-dom";
import React, { createContext } from "react";
// import createContext from "create-react-context";
Enter fullscreen mode Exit fullscreen mode

Next we need to create the context. Context has a Consumer and a Provider

const { Provider, Consumer } = createContext();
Enter fullscreen mode Exit fullscreen mode

Provider is used to pass to him some data in value prop

render() {
    return (
        <Provider value={"React is Awesome!"}>
            nested content...
        </Provider>
    )
}
Enter fullscreen mode Exit fullscreen mode

And Consumer is used to consume that value using render props

render() {
    return (
        <Consumer>
            {(theValue) => {
                return theValue
            }}
        </Consumer>

        // shorthand
        <Consumer>
            {theValue => theValue}
        </Consumer>
    )
}

// output
// React is Awesome!

Enter fullscreen mode Exit fullscreen mode

We may use the Consumer how many times we want.

Now back to our overriding. Here is my app

const App = () => (
  <Provider value={{ location: "/" }}>
    <NestedPath>
      <NestedPath location="haha/">
        <NestedPath>
          <NestedPath>
            <NestedPath>
              <NestedPath />
            </NestedPath>
          </NestedPath>
        </NestedPath>
      </NestedPath>
    </NestedPath>
  </Provider>
);

ReactDOM.render(<App />, document.getElementById("root"));
Enter fullscreen mode Exit fullscreen mode

And here is the output

/
/location/
/location/haha/
/location/haha/location/
/location/haha/location/location/
/location/haha/location/location/location/
Enter fullscreen mode Exit fullscreen mode

And this is my NestedPath component

const NestedPath = ({ location = "location/", children }) => (
    <Consumer>
        {router => (
            <React.Fragment>
                <div>{router.location}</div>
                <Provider value={{ ...router, location: router.location + location }}>
                    {children || null}
                </Provider>
            </React.Fragment>
        )}
    </Consumer>
);
Enter fullscreen mode Exit fullscreen mode

Here as you see inside Provider we override previous one with a new value. And all child Consumers now will take the new value.

Here is a sandbox to play with

https://codesandbox.io/s/lrvv8w784q

Thanks for reading!!! This is a duplicate of my Medium Story!
dev.to is new medium for developers :)

๐Ÿ’– ๐Ÿ’ช ๐Ÿ™… ๐Ÿšฉ
iamandrewluca
Andrei L

Posted on July 6, 2018

Join Our Newsletter. No Spam, Only the good stuff.

Sign up to receive the latest update from our blog.

Related

ยฉ TheLazy.dev

About