组件通信的意义
组件是独立封闭的单元,默认情况下组件只能使用自己的数据(state)
组件化开发的过程中,完整的功能会拆分多个组件,在这个过程中不可避免要传递一些数据
为了能让各组件之间进行互相沟通,数据传递,这个过程就是组件通信
学习目标: 实现父子通信中的父传子,把父组件中的数据传递给子组件
实现步骤:
state
props
接收父组件传过来的数据import React from 'react'
// APP 父组件
// son 子组件
class SonC extends React.Component {
render() {
return <div>我是类子组件:{this.props.msg}</div>
}
}
function SonF(props) {
return <div>我是函数子组件:{props.msg}</div>
}
class App extends React.Component {
state = {
Message: 'this is message',
}
render() {
return (
<>
<SonC msg={this.state.Message} />
<SonF msg={this.state.Message} />
</>
)
}
}
export default App
学习目标: 知道 props 传递时的一些注意事项
js this.props.msg = 'new msg' //不行,不能修改
import React from 'react'
// APP 父组件
// son 子组件
class SonC extends React.Component {
render() {
return <div>我是类子组件:{this.props.msg}</div>
}
}
function SonF(props) {
/*
简洁方法:使用解构赋值 省略props
1.
const {msg,age,cd,child,list,obj} = props
2.function SonF({msg,age,cd,child,list,obj}) {}
*/
const { msg, age, cd, child, list, obj, getmsg } = props
return (
<>
<div>
我是函数子组件:{msg}、{age}、{cd}、{props.list}、{child}
</div>
{props.list.map((item) => (
<p key={item}>{item}</p>
))}
{obj.name}
<button onClick={getmsg}>click</button>
</>
)
}
class App extends React.Component {
state = {
Message: 'this is message',
list: [1, 2, 3],
obj: {
name: 'jack',
age: '19',
},
}
getmsg = () => {
console.log('getmsg')
}
render() {
return (
<>
<SonC msg={this.state.Message} />
<SonF
msg={this.state.Message}
list={this.state.list}
age={23}
obj={this.state.obj}
cd={() => {
console.log(1)
}}
child={<span>look me</span>}
getmsg={this.getmsg}
/>
</>
)
}
}
export default App
实现方法:
子组件调用父组件传递的函数,并且将想要传递的数据当作函数的实参
import React from 'react'
// APP 父组件
// son 子组件
//子组件调用父组件传递的函数,并且将想要传递的数据当作函数的实参
function SonF(props) {
/*调用方法2
function clickHandler(){
props.getmsg("this is son msg")
}
*/
return (
<button
onClick={() => {
props.getmsg('this is son msg')
}}>
click
</button>
)
}
class App extends React.Component {
state = {
Message: 'this is message',
}
getmsg = (date) => {
this.setState({
Message: date,
})
}
render() {
return (
<>
<div>{this.state.Message}</div>
<SonF getmsg={this.getmsg} />
</>
)
}
}
export default App
思路: 通过组件状态提升机制,利用共同的父组件实现兄弟组件通信
实现方法: 1.将共享状态提升到最近的父组件中,由公共组件管理这个状态
import React from 'react'
// APP 父组件
// SonA SonB 子组件
// 目标 将B中的数据传输给A
function SonA(props) {
return <div>this is SonA message/{props.msg}</div>
}
function SonB(props) {
const Bmsg = 'this is Bmsg'
return (
<div>
this is SonA message
<button
onClick={() => {
props.getBmsg(Bmsg)
}}>
click
</button>
</div>
)
}
class App extends React.Component {
state = {
Message: 'this is message',
}
getBmsg = (msg) => {
console.log(msg)
// 将获取的B的数据交给Message
this.setState({
Message: msg,
})
}
render() {
return (
<>
<SonB getBmsg={this.getBmsg} />
<SonA msg={this.state.Message} />
</>
)
}
}
export default App
**学新目标:**了解 Context 机制解决的问题和使用步骤
问题场景
如上图,为一个 React 形成的嵌套组件树,如果我们要从 App 组件向任意下层组件传递数据,采用一层一层 props 往下传递会很繁琐,我们该怎么办呢
实现步骤:
创建 Context 对象导出 Provider 和 Consumer 对象
const {Provider , Consumer} = createContext()
使用 Provider 包裹根组件提供的数据
<Provider value={this.state.message}>
{/* 根组件*/}
</Provider>
需要用到数据的组件使用 Consumer 包裹获取数据
<Consumer>
{value => /* 基于Context值进行渲染 */}
</Consumer>
代码实现:
import React, { createContext } from 'react'
//1.
const { Provider, Consumer } = createContext()
//App->A->B
//App数据->B
function ConA() {
return (
<div>
this is A
<ConB />
</div>
)
}
function ConB() {
return (
// 3. 通过Consumer使用数据
<div>
this is B<Consumer>{(value) => <span>{value}</span>}</Consumer>
</div>
)
}
class App extends React.Component {
state = {
msg: 'this is AppMsg',
}
render() {
return (
// 通过Provider提供数据
<Provider value={this.state.msg}>
<div>
<ConA />
</div>
</Provider>
)
}
}
export default App