这是我参与11月更文挑战的第4天,活动详情查看:2021最后一次更文挑战
一、Props与State
Props:Props可以认为是父组件传给子组件的参数,这个参数对于子组件来说是只读的(纯净的),子组件无法直接对其进行修改。但是,子组件可以通过触发父组件从Props中传来的函数对父组件的State进行修改(则有可能会修改到传进来的Props)
State:State指的是当前组件的一个状态,组件可以通过方法来对当前的状态进行修改,从而触发页面的重新渲染,可以通过this.setState对当前状态进行修改,但是要注意这一操作是异步的
二、单项数据流之Props
父-子通信
常用方法:Props,通过Props传值让子组件发生变化
代码如下:
//父组件
constructor(props){
super(props);
this.state = {
content:"父组件传给子组件的内容"
}
}
render() {
return (
<div>
<Children change={this.changeContent} content={this.state.content} />
<button onClick={ ()=>{ this.setState({ content:"父组件内容发生了改变" }) } }>点击改变传值内容</button>
</div>
)
}
changeContent(content) {
this.setState({
content:content
})
}
//子组件
render() {
return (
<div>{this.props.content}</div>
)
}
可得到效果如下:
子-父通信
原理:父组件通过Props传入可以改变自己State的函数,随后由子组件触发该函数,该函数修改父组件State达到子-父组件通信的目的,代码如下:
//父组件
render() {
return (
<div>
<div>{this.state.content}</div>
<Children change={this.changeContent} content={this.state.content} />
</div>
)
}
changeContent = (content) => {
this.setState({
content:content
})
}
//子组件
render() {
return (
<div>
<button onClick={this.changeParent}>修改父组件内容</button>
</div>
)
}
changeParent = () => {
this.props.change("父组件内容被修改了");
}
可得以下效果:
兄弟组件通信
原理:两个兄弟组件A、B之间进行通信,可以理解为A通过Props调用父组件的函数修改State从而更新B的Props
//父组件
constructor(props) {
super(props)
this.state = {
content:"B组件初始内容"
}
}
render() {
return (
<div>
<NewChildren toB={this.state.content} />
<Children change={this.changeContent} content={this.state.content} />
</div>
)
}
changeContent = (content) => {
this.setState({
content:content
})
}
//兄弟A
render() {
return (
<div>
<button onClick={this.changeParent}>兄弟A</button>
</div>
)
}
changeParent = () => {
this.props.change("兄弟A修改兄弟B(组件间通信)");
}
//兄弟B
render() {
return (
<div>
<div>兄弟B:{this.props.toB}</div>
</div>
)
}
可得以下效果:
三、发布订阅模式
发布订阅模式也是组件间通信的老演员了,我们在这里实现以下发布订阅模式并且在React里尝试使用:
- 发布订阅模式的实现
class EventEmitter {
constructor() {
this.eventMap = {}
}
on(name,handle) {
if(!(handle instanceof Function)){
return new Error('请传一个函数');
}
if(this.eventMap[name]){
this.eventMap[name].push(handle);
}else{
this.eventMap[name] = [];
this.eventMap[name].push(handle);
}
}
emit(name,params) {
if(this.eventMap[name]){
this.eventMap[name].forEach((handle,index)=>{
handle(params);
})
}
}
off(name,handle) {
this.eventMap[name].splice(this.eventMap[name].indexOf(handle),1)
}
}
export default new EventEmitter()
- 发布订阅模式在
React中的使用
//父组件
constructor(props) {
super(props)
this.state = {
content:"发布订阅模式"
}
}
render() {
return (
<div>
<button onClick={this.changeContent}>添加监听事件</button>
<Children content={this.state.content} />
</div>
)
}
changeContent = () => {
EventEmitter.on("change",(content)=>{
this.setState({
content:content
})
})
}
//子组件
render() {
return (
<div>
<div>{this.props.content}</div>
<button onClick={this.changeParent}>发布订阅触发</button>
</div>
)
}
changeParent = () => {
EventEmitter.emit("change","发布订阅模式生效");
}
可得以下效果:
点击监听事件添加以后即可进行触发