Monday, June 21, 2021

What is React-JS Legacy Context

Suppose you have a structure like:


class Button extends React.Component {

  render() {

    return (

      <button style={{background: this.props.color}}>

        {this.props.children}

      </button>

    );

  }

}


class Message extends React.Component {

  render() {

    return (

      <div>

        {this.props.text} <Button color={this.props.color}>Delete</Button>

      </div>

    );

  }

}


class MessageList extends React.Component {

  render() {

    const color = "purple";

    const children = this.props.messages.map((message) =>

      <Message text={message.text} color={color} />

    );

    return <div>{children}</div>;

  }

}



In this example, we manually thread through a color prop in order to style the Button and Message components appropriately. Using context, we can pass this through the tree automatically:


import PropTypes from 'prop-types';


class Button extends React.Component {

  render() {

    return (

      <button style={{background: this.context.color}}>

        {this.props.children}

      </button>

    );

  }

}


Button.contextTypes = {

  color: PropTypes.string

};

class Message extends React.Component {

  render() {

    return (

      <div>

        {this.props.text} <Button>Delete</Button>

      </div>

    );

  }

}


class MessageList extends React.Component {

  getChildContext() {

    return {color: "purple"};

  }

  render() {

    const children = this.props.messages.map((message) =>

      <Message text={message.text} />

    );

    return <div>{children}</div>;

  }

}


MessageList.childContextTypes = {

  color: PropTypes.string

};



By adding childContextTypes and getChildContext to MessageList (the context provider), React passes the information down automatically and any component in the subtree (in this case, Button) can access it by defining contextTypes.


If contextTypes is not defined, then context will be an empty object.


Context can also let you build an API where parents and children communicate. For example, one library that works this way is React Router V4:


import { BrowserRouter as Router, Route, Link } from 'react-router-dom';


const BasicExample = () => (

  <Router>

    <div>

      <ul>

        <li><Link to="/">Home</Link></li>

        <li><Link to="/about">About</Link></li>

        <li><Link to="/topics">Topics</Link></li>

      </ul>


      <hr />


      <Route exact path="/" component={Home} />

      <Route path="/about" component={About} />

      <Route path="/topics" component={Topics} />

    </div>

  </Router>

);



By passing down some information from the Router component, each Link and Route can communicate back to the containing Router.


Before you build components with an API similar to this, consider if there are cleaner alternatives. For example, you can pass entire React components as props if you’d like to.



References:

https://reactjs.org/docs/legacy-context.html

No comments:

Post a Comment