Components are independent and closed units . By default, components can only use their own data (state)
In the process of component development, the complete function will split multiple components, and it is inevitable to transfer some data to each other in this process
In order to allow each component to communicate with each other and transfer data, this process is component communication
- Father-Son Relationship - Most Important
- Sibling relationship - custom event mode generates technical method eventBus / communicates through a common parent component
- Other relations - mobx / redux / zustand
From father to son
Implementation steps
- The parent component provides the data to be passed −
state
- Give the child component label
添加属性
value the data in the state - The child component receives the data passed from the parent component
props
by- Class components use this.props to get the props object
- Functional components get props objects directly through parameters
Code
import React from 'react'
// 函数式子组件
function FSon(props) {
console.log(props)
return (
<div>
子组件1
{props.msg}
</div>
)
}
// 类子组件
class CSon extends React.Component {
render() {
return (
<div>
子组件2
{this.props.msg}
</div>
)
}
}
// 父组件
class App extends React.Component {
state = {
message: 'this is message'
}
render() {
return (
<div>
<div>父组件</div>
<FSon msg={this.state.message} />
<CSon msg={this.state.message} />
</div>
)
}
}
export default App
props description
1. props is a read-only object (readonly)
According to the requirements of a single data stream, subcomponents can only read the data in props and cannot modify it
2. props can pass arbitrary data
numbers, strings, booleans, arrays, objects,函数、JSX
The code example is as follows
class App extends React.Component {
state = {
message: 'this is message'
}
render() {
return (
<div>
<div>父组件</div>
<FSon
msg={this.state.message}
age={20}
isMan={true}
cb={() => { console.log(1) }}
child={<span>this is child</span>}
/>
<CSon msg={this.state.message} />
</div>
)
}
}
Fulfillment from son to father
Mantra : The parent component passes a callback function to the child component, and the child component calls
Implementation steps
- The parent component provides a callback function - used to receive data
- Pass the function as the value of the property to the child component
- The child component calls the callback function through props
- Pass the data in the child component as a parameter to the callback function
Code
import React from 'react'
// 子组件
function Son(props) {
function handleClick() {
// 调用父组件传递过来的回调函数 并注入参数
props.changeMsg('this is newMessage')
}
return (
<div>
{props.msg}
<button onClick={handleClick}>change</button>
</div>
)
}
class App extends React.Component {
state = {
message: 'this is message'
}
// 提供回调函数
changeMessage = (newMsg) => {
console.log('子组件传过来的数据:',newMsg)
this.setState({
message: newMsg
})
}
render() {
return (
<div>
<div>父组件</div>
<Son
msg={this.state.message}
// 传递给子组件
changeMsg={this.changeMessage}
/>
</div>
)
}
}
export default App
Sibling communication
Core idea: through the state promotion mechanism, use the common parent component to realize brother communication
Implementation steps
- Promote shared state to the nearest common parent component , which manages this state
- Provide shared status
- Provides methods for manipulating shared state
- Subcomponents that want to receive data state receive data via props
- Subcomponents that want to pass data status receive methods through props , and call methods to pass data
Code
import React from 'react'
// 子组件A 负责接收来自子组件B传递给父组件的数据
function SonA(props) {
return (
<div>
SonA
{props.msg}
</div>
)
}
// 子组件B 负责传递数据给父组件,父组件再转给子组件A
function SonB(props) {
return (
<div>
SonB
<button onClick={() => props.changeMsg('new message')}>changeMsg</button>
</div>
)
}
// 父组件
class App extends React.Component {
// 父组件提供状态数据
state = {
message: 'this is message'
}
// 父组件提供修改数据的方法
changeMsg = (newMsg) => {
this.setState({
message: newMsg
})
}
render() {
return (
<>
{/* 接收数据的组件 */}
<SonA msg={this.state.message} />
{/* 修改数据的组件 */}
<SonB changeMsg={this.changeMsg} />
</>
)
}
}
export default App
Cross-component communication Context
The above picture is a nested component tree formed by react. What should we do if we want to pass data from the App component to any lower component? At present, the way we can take is to pass down the props layer by layer, which is obviously very cumbersome. . .
Then, Context provides a way to transfer data between component trees without manually adding props to each layer of components
Implementation steps
1- Create a Context object to export Provider and Consumer objects
import React, { createContext } from 'react'
const { Provider, Consumer } = createContext()
2- Use Provider to wrap the upper component to provide data
<Provider value={this.state.message}>
{/* 根组件 */}
</Provider>
3- Components that need data use the Consumer package to obtain data
<Consumer >
{value => /* 基于 context 值进行渲染*/}
</Consumer>
Code
import React, { createContext } from 'react'
// 1. 创建Context对象
const { Provider, Consumer } = createContext()
// 3. 消费/获取数据
function ComC() {
return (
<Consumer >
{value => <div>{value}</div>}
</Consumer>
)
}
function ComA() {
return (
<ComC/>
)
}
// 2. 提供数据
class App extends React.Component {
state = {
message: 'this is message'
}
render() {
return (
<Provider value={this.state.message}>
<div className="app">
<ComA />
</div>
</Provider>
)
}
}
export default App
For more knowledge about React components & props, visit the official website.