As a newcomer to React, you may encounter trouble in communication between components because of the one-way data flow characteristics of React. The following article will give you a detailed introduction. Let's take a look at a picture before we start:
Reaction component communication
Several situations that require communication between components.
The parent component communicates with the child component.
The child component communicates with the parent component.
Cross-level component communication
Communication between components without nested relationships.
1. The parent component communicates with the child component.
React data flow is one-way, and communication between parent and child components is also the most common. The parent component passes the required information to the child component through props.
Child.jsx
Import React from "react";
Import PropTypes from "prop-types"
Export default function children ({name }) {
return & lth 1 & gt; Hello, {name}</h1> ;
}
Child.propTypes = {
Name:prop types. string. is required.
};
Parent.jsx
Import React from "react", {Component };;
Import children from'. /Child ';
Class parent extension {
render() {
Return (
& ltdiv & gt
& ltchild name = " Sara "/& gt;
& lt/div & gt;
);
}
}
Export the default parent;
2. The child component communicates with the parent component.
Use callback function
Use a custom event mechanism
Callback function
The implementation can hide its functions by clicking the Hide Component button in the subcomponent.
List3.jsx
Import React from "react", {Component };;
Import PropTypes from "prop-types"
Category List 3 Extensions {
Static attribute type = {
Hideconponent: proptypes. func.is is required.
}
render() {
Return (
& ltdiv & gt
Haha, I'm List3
& ltbutton onClick = { this . props . hideconfonent } & gt; Hide List3 components
& lt/div & gt;
);
}
}
Export default list 3;
Application, jsx
Import React from "react", {Component };;
Import Listing 3 from'. /components/list 3 ';
Export default class application extension {
Constructor (... args) (
Super (... args);
this.state = {
IsShowList3: false,
};
}
show component =()= & gt; {
this.setState({
IsShowList3: That's right.
});
}
hideconfonent =()= & gt; {
this.setState({
IsShowList3: false,
});
}
render() {
Return (
& ltdiv & gt
& ltbutton onClick = { this . show component } & gt; Display list component
{
this.state.isShowList3?
& ltlist 3 hideconfonent = { this . hideconfonent }/& gt;
:
empty
}
& lt/div & gt;
);
}
}
Observing the implementation method, we can find that it is the same as the traditional callback function, and setState and callback function usually appear in pairs, because callback function is a traditional function to transform internal state;
3. Cross-level component communication
Layered components through props.
For example, in order to communicate between component A and component B, the parent components of component A and component B should be found first. A communicates with component C first, and component C communicates with component B through props. At this point, component C plays the role of middleware.
Use context
Context is a global variable, just like a big container, which can be accessed anywhere. We can put the information we want to communicate in context and then get it at will in other components.
However, React officials do not recommend using a large number of contexts. Although it can reduce layer-by-layer transmission, when the component structure is complex, we don't know where the context comes from. Moreover, context is a global variable, which is the chief culprit of application confusion.
Use context
Component relationship in the following example: ListItem is a subcomponent of List, and List is a subcomponent of app.
ListItem.jsx
Import React from "react", {Component };;
Import PropTypes from "prop-types"
Class ListItem extension {
//The subcomponent declares that it wants to use the context.
Static context type = {
color: PropTypes.string,
}
Static attribute type = {
Value: PropTypes.string,
}
render() {
const { value } = this.props
Return (
& lt Li style = {{background: this.context.color}} >
& ltspan & gt{ value } & lt/span>。
& lt/ Li>
);
}
}
Export default list items;
List.jsx
Import ListItem from'. /ListItem ';
Category list extension component {
//The parent component declares that it supports context.
Static childContextTypes = {
color: PropTypes.string,
}
Static attribute type = {
list: PropTypes.array,
}
//Provide a function to return the corresponding context object.
getChildContext() {
Return {
Color,' red',
};
}
render() {
const { list } = this.props
Return (
& ltdiv & gt
& ltul & gt
{
list.map((entry,index)= & gt;
& ltListItem key = { ` list-$ { index } `} value = { entry . text }/& gt; ,
)
}
& lt/ul & gt;
& lt/div & gt;
);
}
}
Export the default list;
app.jsx
Import React from "react", {Component };;
Import list from'. /Component/List';
Constant list = [
{
Text: "theme 1",
},
{
Text: "Theme 2",
},
];
Export default class application extension {
render() {
Return (
& ltdiv & gt
& lt catalog
list={list}
/& gt;
& lt/div & gt;
);
}
}
4. Component communication without nesting relationship
Use a custom event mechanism
In the componentDidMount event, if the component installation is complete, subscribe to the event; When uninstalling a component, unsubscribe from the event in the componentWillUnmount event;
Take the common publish/subscribe mode as an example, and use the Node.js event module of the browser version to realize it.
Use custom events.
Component relationships in the following examples: List 1 and List2 are not nested, and App is their parent component;
Realize such a function: click a button in List2 to change the information display in List 1
First, you need to install the events package in your project:
Npm Installation Event-Save
Create a new util directory under src and build an events.js in it.
Import {eventemitter} from Events;
Export the default new eventemitter ();
list 1.jsx
Import React from "react", {Component };;
From' import emitter' ../util/events';
Category list extension component {
The builder (props) {
Super (props);
this.state = {
Message: List 1,
};
}
componentidmount(){
//Declare a custom event after the component is loaded.
this . event emitter = emitter . addlistener(' change message ',(message)= & gt; {
this.setState({
News,
});
});
}
componentWillUnmount() {
emitter . remove listener(this . event emitter);
}
render() {
Return (
& ltdiv & gt
{this.state.message}
& lt/div & gt;
);
}
}
Export the default list;
List2.jsx
Import React from "react", {Component };;
From' import emitter' ../util/events';
Category List 2 Extension Component {
handle click =(message)= & gt; {
emitter.emit('changeMessage ',message);
};
render() {
Return (
& ltdiv & gt
& ltbutton onClick = { this . handle click . bind(this,' list 2 ')} & gt; Click I to change the information displayed in the List 1 component.
& lt/div & gt;
);
}
}
APP.jsx
Import React from "react", {Component };;
Import list from' 1. /components/list 1 ';
Import Listing 2 from'. /components/list 2 ';
Export default class application extension {
render() {
Return (
& ltdiv & gt
& ltList 1 />
& ltList2 />
& lt/div & gt;
);
}
}
Custom event is a typical publish-subscribe mode, and communication between components is realized by adding listeners and triggering events to event objects.
abstract
Parent component communicates with child component: props
Communication between Child Component and Parent Component: Callback Function/Custom Event
Cross-layer component communication: passing props/context layer by layer.
Communication between components without nested relationships: custom events
When communicating with components, we mainly look at the specific needs of the business and choose the most suitable one;
When the business logic is complex to a certain extent, we can consider introducing state management tools such as Mobx and Redux.
abstract