学习目标:掌握React中的组件通信方式
目录
一、父传子
1、方式
父组件通过在子组件标签中添加属性传递参数,子组件通过props就可以获取
2、示例代码
import React,{Component} from "react";
// 创建类组件
class Test extends Component{
render(){
return(
<>
{/* 通过props获取 */}
<p>我是子组件,父组件name是{this.props.name}</p>
</>
);
}
}
class App extends Component{
state={
name:'KongKwan',
age:18
}
render(){
return (
<div className="App">
{/* 子组件标签中设置属性 */}
<Test name={this.state.name} age={this.state.age}/>
</div>
);
}
}
export default App;
3、说明
(1)如果父组件是函数组件,数据可以是来自一个变量,如const name = 'KongKwan'
(2)函数组件是需要接收参数的,可以是props,也可以直接在接收的时候进行解构,或者接收到props之后再进行解构,示例如下
function Test(props){
const {name,age}=props
return(
<div>{name},{age}</div>
)
}
(3)根据单项数据流的要求,子组件只能读取props中的数据,不能进行修改
二、子传父
1、方式
子组件通过调用父组件的函数,通过传参的方式传递数据
2、示例代码
当点击按钮的时候,能够将子组件传递过来的name和age进行渲染
import React,{Component} from "react";
function Test(props){
const name='kk'
const age=18
const handleClick=()=>{
// 子组件调用函数,并传递参数
props.getSonData(name,age)
}
return(
<button onClick={handleClick}>show</button>
)
}
class App extends Component{
state={
fName:'name',
fAge:0
}
// 设置获取子组件数据的回调函数
getSonData=(name,age)=>{
this.setState({
fName:name,
fAge:age
})
}
render(){
return (
<>
{/* 将回调函数传递给子组件 */}
<Test getSonData={this.getSonData}/>
<div>{this.state.fName}——{this.state.fAge}</div>
</>
);
}
}
export default App;
三、兄弟间通信
1、方式
通过共同的父组件来进行通信(图:来自与柴柴老师)
2、练手
从SonB中传递数据给SonA
实例代码:
import React,{Component} from "react";
function SonA(props){
return(
<div>this is SonA,我得到来自SonB的数据是{props.name}</div>
)
}
class SonB extends Component{
handleClick=()=>{
this.props.getSonBData('kk')
}
render(){
return(
<div onClick={this.handleClick}>this is SonB</div>
)
}
}
class App extends Component{
state={
fName:""
}
// 设置获取子组件数据的回调函数
getSonBData=(name)=>{
this.setState({
fName:name,
})
}
render(){
return (
<>
{/* 将回调函数传递给子组件SonB */}
<SonB getSonBData={this.getSonBData}/>
{/* 将从SonB得到的数据传给SonA */}
<SonA name={this.state.fName}/>
</>
);
}
}
export default App;
四、跨组件通信
1、问题
上图(来自于柴柴老师)是一个react形成的嵌套组件树,如何实现App组件向任意一个下层组件传递数据?
2、方式
通过React提供的Context对象
3、示例
App嵌套了ComA,ComA又引用了ComC,实现App传递数据给ComC
import React,{Component,createContext}from "react";
// 创建对象实例
const { Provider, Consumer } = createContext()
function ComA(){
return(
<>
<div>this is SonA</div>
<ComC/>
</>
)
}
function ComC(){
return(
// 使用数据
<Consumer>
{value=><div>this is SonC,我得到来自App的数据是{value}</div>}
</Consumer>
)
}
class App extends Component{
state={
name:'kk'
}
render(){
return (
// 提供数据
<Provider value={this.state.name}>
<ComA></ComA>
</Provider>
);
}
}
export default App;
4、留下疑问
(1)这样会不会造成数据来源不明呢
(2)还有个问题,如果是要在一定的条件下(比如点击之后)传递数据的话,怎么办?
五、阶段练习
实现从父组件中获取列表数据,进行渲染,并给每个列表项加一个删除按钮,点击之后删除对应的列表项
示例代码:
import React,{Component}from "react";
function ComA(props){
const {manList,handleDelete} = props
const spanStyle ={
padding:'10px',
color:'blue'
}
return(
<ul>
{manList.map(item=>
<li key={item.id}>
{item.name}
<span style={spanStyle} onClick={()=>handleDelete(item.id)}>
删除
</span>
</li>
)}
</ul>
)
}
class App extends Component{
state={
manList:[
{id:1,name:'BillKin'},
{id:2,name:'PP'},
{id:3,name:'Ohm'},
{id:4,name:'NaNon'}
]
}
handleDelete=(id)=>{
this.setState({
manList:this.state.manList.filter(item=>item.id!==id)
})
}
render(){
return (
<ComA manList={this.state.manList} handleDelete={this.handleDelete}></ComA>
)
}
}
export default App;