携手创作,共同成长!这是我参与「掘金日新计划 · 8 月更文挑战」的第15天,点击查看活动详情
1. 组件通讯的三种方式
1.1 父组件 -> 子组件
- 父组件提供要传递的 state 数据
- 给子组件标签添加属性,值为 state 中的数据
- 子组件中通过 props 接收父组件中传递的数据
父组件
class Parent extends React.Component {
state = {
lastName: '邱'
}
render() {
return (
<div>
传递数据给子组件:<Child name={this.state.lastName} />
</div>
)
}
}
子组件
const Child = (props) => {
return (
<div>子组件接收到数据:{props.name}</div>
)
}
1.2. 子组件 -> 父组件
思路:利用回调函数,父组件提供回调,子组件调用,将要传递的数据作为回调函数的参数
- 父组件提供一个回调函数(用于接收数据)
- 将该函数作为属性的值,传递给子组件
- 子组件通过 props 调用回调函数
- 将子组件的数据作为参数传递给回调函数
// 导入ract
import React from 'react'
import ReactDOM from 'react-dom'
// 父组件
class Parent extends React.Component {
// 共享状态
state = {
message: ''
}
// 父组件提供的回调函数,用来接收数据
getChildMsg = (data) => {
console.log('接收子组件中传过来的数据:', data)
// 父组件值更新为子组件传递过来的值
this.setState({
message: data
})
}
render() {
return (
<div className='parent'>
父组件:{this.state.message}
<Child getMsg={this.getChildMsg}></Child>
</div>
)
}
}
// 子组件
class Child extends React.Component {
state = {
msg: '子组件传递的数据'
}
handleClick = () => {
// 子组件调用父组件传递过来的回调函数
this.props.getMsg(this.state.msg)
}
render() {
return (
<div className='child'>
子组件:{this.state.msg}
<button onClick={this.handleClick}>点我,将子组件数据传递给父组件</button>
</div>
)
}
}
// 渲染
ReactDOM.render(<Parent />, document.getElementById('root'))
1.3. 兄弟组件
- 将共享状态提升到最近的公共父组件中,由公共父组件管理这个状态
- 思想:状态提升
- 公共父组件职责:1.提供共享状态 2.提供操作共享状态的方法
- 要通讯的子组件只需通过 props 接收状态或操作状态的
// 导入ract
import React from 'react'
import ReactDOM from 'react-dom'
// 父组件
class Parent extends React.Component {
// 共享状态
state = {
count: 0
}
// 操作共享状态的方法
increment = () => {
this.setState({
count: this.state.count + 1
})
}
calc = () => {
this.setState({
count: this.state.count - 1
})
}
render() {
return (
<div>
<Child1 num={this.state.count}></Child1>
<Child2 onIncrement={this.increment}></Child2>
<br />
<Child3 onCalc={this.calc}></Child3>
</div>
)
}
}
// 子组件1
const Child1 = (props) => {
return (
<h1>计数器:{props.num}</h1>
)
}
// 子组件2
const Child2 = (props) => {
return (
<button onClick={() => props.onIncrement()}>+1</button>
)
}
// 子组件3
const Child3 = (props) => {
return (
<button onClick={() => props.onCalc()}>-1</button>
)
}
// 渲染
ReactDOM.render(<Parent />, document.getElementById('root'))
2. Context
思考:
App 组件要传递数据给 Child 组件,该如何处理?
- 处理方式:使用 props 一层层组件往下传递(繁琐)
- 更好的方式:使用 Context
- 作用:跨组件传递数据(比如:主题、语言等)
使用步骤:
- 调用 React.createContext() 创建 Provider(提供数据)和 Consumer(消费数据)两个组件。
- 使用 Provider 组件作为父节点。
- 设置 value 属性,表示要传递的数据。
- 调用 Consumer 组件接收数据。
// 导入ract
import React from 'react'
import ReactDOM from 'react-dom'
// 1.调用 React.createContext() 创建 Provider(提供数据)和 Consumer(消费数据)两个组件。
const { Provider, Consumer } = React.createContext()
// 2.使用 Provider 组件作为父节点。
// 3.设置 value 属性,表示要传递的数据。
class App extends React.Component {
render() {
return (
<Provider value="red">
<div className='app'>
<Node />
</div>
</Provider>
)
}
}
const Node = props => {
return (
<div className='node'>
<SubNode />
</div>
)
}
const SubNode = props => {
return (
<div className='subNode'>
<Child />
</div>
)
}
// 4.调用 Consumer 组件接收数据。
const Child = props => {
return (
<Consumer>
{
data => (
<div className='child'>
<span>我是子节点 -- {data}</span>
</div>
)
}
</Consumer>
)
}
// 渲染
ReactDOM.render(<App />, document.getElementById('root'))