React(十二)- React拓展:renderProps、ErrorBoundary及组件间通信方式总结
一. renderProps拓展
如何向组件内部动态传入带内容的结构(标签)?
React中:
- 使用
children props
: 通过组件标签体传入结构,但是有个问题:如果B组件需要A组件内的数据,那做不到。
<A>
<B>xxxx</B>
</A>
- 使用
render props
: 通过组件标签属性传入结构,而且可以携带数据,一般用render
函数属性。
<A render={(data) => <C data={data}></C>}></A>
例如案例:
import React, { Component } from 'react'
import './index.css'
export default class Parent extends Component {
render() {
return (
<div className="parent">
<h3>我是Parent组件</h3>
<A render={(name) => <B name={name} />} />
</div>
)
}
}
class A extends Component {
state = { name: 'tom' }
render() {
const { name } = this.state
return (
<div className="child">
<h3>我是A组件</h3>
{this.props.render(name)}
</div>
)
}
}
class B extends Component {
render() {
console.log('B---render')
return (
<div className="grand">
<h3>我是B组件:{this.props.name}</h3>
</div>
)
}
}
页面效果如下:
我们只需要更改最外层的组件,就可以动态的传入带内容的标签,更加方便:
二. ErrorBoundary拓展
ErrorBoundary:用来捕获后代组件错误,渲染出备用页面。
其特点如下:
- 只能捕获后代组件生命周期产生的错误。
- 不能捕获自己组件产生的错误和其他组件在合成事件、定时器中产生的错误。
案例:
Child
组件:
import React, { Component } from 'react'
export default class Child extends Component {
state = {
users: '' // 根据下文的写法,users应该是个数组,每个元素是个对象,但是这里给了个空字符串,因此项目运行肯定会报错
}
render() {
return (
<div>
<h2>Child组件</h2>
{
this.state.users.map((obj) => {
return <h4 key={obj.id}>{obj.name}----{obj.name}</h4>
})
}
</div>
)
}
}
Parent
组件:
import React, { Component } from 'react'
import Child from './Child'
export default class Parent extends Component {
state = {
hasError: ''// 用于标识子组件是否产生错误
}
// 当Parent的子组件出现报错的时候,会触发这个方法,并携带错误信息
static getDerivedStateFromError(error) {
console.log(error)
return { hasError: error }
}
// 一般用于统计页面的错误,并将请求发送到后台去。
componentDidCatch(error, info) {
console.log(error, info)
}
render() {
return (
<div>
<h2>Parent组件</h2>
{this.state.hasError ? <h2>出错啦!</h2> : <Child />}
</div>
)
}
}
打包并运行:
npm run build
serve build
访问页面:(同时能看到成功捕捉到了对应的异常。)
三. 组件间通信方式总结
首先,React组件之间有什么关系呢?
- 父子组件
- 兄弟组件(非嵌套组件)
- 祖孙组件(跨级组件)
React组件之间的通信方式有:
- props:第一种:
children props
第二种:render props
// children props
<A>
<B>xxxx</B>
</A>
// render props
<A render={(data) => <C data={data}></C>}></A>
- 消息订阅-发布:pubs-sub、event等等,查看React(六)- React解决跨域请求及订阅发布的使用
- Redux之间数据共享,查看React(八)- ReactUI组件库及Redux的使用
- Context:生产者-消费者模式
<xxxContext.Provider value={数据}>
<子组件/>
</xxxContext.Provider>
<xxxContext.Consumer>
{
value => ( // value就是context中的value数据
要显示的内容
)
}
</xxxContext.Consumer>