An overview of the

In Chapter 1, we mentioned that Data flow is a big feature of React. In the idea of React, the page is completely driven by Data, that is, UI= F (Data). React data includes props and state. The difference is that state is used to manage the UI state of components, while props is used to communicate between components. Meanwhile, the most important feature of React data flow is that it is one-way, that is, one-way data flow. In this way, React automatically updates the UI of its descendants when the user changes the state of a component.

Communication between components

Communication between parent and child components

React communication between parent and child components is the most basic communication between React components. The parent component only needs to pass the content that needs to be passed to the child component through component properties:

class Father extends React.Component {
  render() {
    return (
      <Child {...props} />
    );
  }
}
Copy the code

In the one-way data flow of React, the child components are not allowed to modify or pass props to the parent component directly. The communication between the child components and the parent component needs to be realized through callback functions.

class Father extends React.Component {
handleClick(name) {
  console.log(`click ${name}`);
}  render() {
    return (
      <Child {...props} handleClick={this.handleClick} />
    );
  }
}

class Child extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
      name: 'child'
    }
  }
  click() {
    this.props.handleClick && this.props.handleClick(this.state.name);
  }

  render() {
    return (
      <div onClick={this.click}>click</div>
    );
  }
}
Copy the code

Sibling communication

Sibling components in React also cannot communicate directly, but can communicate via their common parent. The method is also simple, where a child component passes information to the parent component in the manner of the above callbacks, and the parent component passes information to the other component via props.

Communication across tiers of components

One obvious problem with component communication is that there are multiple layers of component communication. It is possible to pass layers of props and props, but it is not reasonable to pass layers of props or handle callbacks, which makes the code readable and maintainable. React provides a context so that multiple components can share some properties.

React does not recommend using context. Instead, it recommends passing components instead of properties to solve the problem:

We need to pass the Avatar properties to the Avatar component.

<Page user={user} avatarSize={avatarSize} /> // ... Apply colours to a drawing gives... <PageLayout user={user} avatarSize={avatarSize} /> // ... Apply colours to a drawing gives... <NavigationBar user={user} avatarSize={avatarSize} /> // ... Apply colours to a drawing gives... <Link href={user.permalink}> <Avatar user={user} size={avatarSize} /> </Link>Copy the code

Only the Avatar uses these parameters. React recommends transferring the Avatar

function Page(props) {
  const user = props.user;
  const content = <Feed user={user} />;
  const topBar = (
    <NavigationBar>
      <Link href={user.permalink}>
        <Avatar user={user} size={props.avatarSize} />
      </Link>
    </NavigationBar>
  );
  return (
    <PageLayout
      topBar={topBar}
      content={content}
    />
  );
}
Copy the code

Context allows you to broadcast this data to all components in the component tree, all of which have access to the data and to subsequent data updates.

import {ThemeContext, themes} from './theme-context'; import ThemeTogglerButton from './theme-toggler-button'; class App extends React.Component { constructor(props) { super(props); this.toggleTheme = () => { this.setState(state => ({ theme: state.theme === themes.dark ? themes.light : themes.dark, })); }; this.state = { theme: themes.light, toggleTheme: this.toggleTheme, }; } render() {return (< themecontext.provider value={this.state}> <Content /> </ThemeContext.Provider> ); } } function Content() { return ( <div> <ThemeTogglerButton /> </div> ); } ReactDOM.render(<App />, document.root);Copy the code

import {ThemeContext} from './theme-context'; Function ThemeTogglerButton() {// ThemeToggler button not only gets the Theme value, It also gets a toggleTheme function from the context return (themecontext.consumer > {({theme, toggleTheme}) => ( <button onClick={toggleTheme} style={{backgroundColor: theme.background}}> Toggle Theme </button> )} </ThemeContext.Consumer> ); } export default ThemeTogglerButton; export const ThemeContext = React.createContext({ theme: themes.dark, toggleTheme: () => {}, });Copy the code

In this demo we create a context using createContext and share it with all the child components using context.Provider. The child components can get the shared properties through context.consumer. It is important to note that we share a function with the child component, which can be called to update the state of the parent component to achieve two-way data communication.

Component communication is carried out through a publish-subscribe pattern

In component communication without any relationship, such as the communication between two routing pages in a single-page application, we can use the publishable-subscribe mode to communicate, and we simulated and implemented a simple EventEmitter.

class EventEmitter { constructor() { this.eventMap = {}; } on(name, fn) { this.eventMap[name] ? this.eventMap[name].push(fn) : this.eventMap[name] = [fn]; } emit(name, ... args) { if(! this.eventMap.hasOwnProperty(name)) return; this.eventMap[name].map((fn) => { fn.apply(this, args); }) } off(name) { if(! this.eventMap[name]) { return; } else { delete this.eventMap[name]; }}}Copy the code

Through Redux, Mobx and other state management tools to achieve component communication

I believe that you have come into contact with Redux, Mobx and other state management tools in your daily development process. State management tools are mainly used to assist in the state management of complex large-scale applications, but they can also realize the communication of various components in combination with redux-React libraries. Redux-react essentially uses the React Context API to share state stored in the store. Since the Context API was covered in the previous article, and Redux and Mobx will be covered in more detail in the next chapter on state Management, we won’t cover it here.

conclusion

  1. React processes data flows using props and state. Props processes communication between components, and state manages component states.

  2. Communication between components is divided into:

  3. Parent – child component communication is realized by passing props and callback functions directly

  4. Sibling communication is mediated through the common parent

  5. Components can be passed across hierarchies or handled using context

  6. Communication between different components can also be achieved through a publish-subscribe pattern and a state management library