React扩展:fragment、Context
目录
1.fragment
fragment标签能包裹其它标签,但最后不会渲染到DOM树上。
import React, { Component, Fragment } from 'react'
export default class Demo extends Component {
render() {
return (
<Fragment>
<input type="text" />
<input type="text" />
</Fragment>
)
}
}
通常来说,render函数返回的东西需要用<div></div>包裹。用fragment标签包裹,最后fragment也不会被渲染,相较于前者,能少一对<div></div>。
2.Context
父子组件间通信用props就行,祖组件和后代组件之间(间隔不止一代)通信用Context。
应用开发中一般不用Context,一般都用它封装React插件。
/src/components/Demo/index.jsx
import React, { Component } from 'react'
import './index.css'
// 创建Context对象
const MyContext = React.createContext();
const {Provider,Consumer} = MyContext
export default class A extends Component {
state = {username:'tom'}
render() {
const {username} = this.state
return (
<div className='parent'>
<div>A组件</div>
<div>用户名:{username}</div>
<Provider value={username}>
<B />
</Provider>
</div>
)
}
}
class B extends Component {
render() {
return (
<div className='child'>
<div>B组件</div>
<C />
</div>
)
}
}
/*
// 类式组件
class C extends Component {
// 声明接收context
static contextType = MyContext
render() {
return (
<div className='grandchild'>
<div>C组件</div>
<div>从A组件接收到的用户名:{this.context}</div>
</div>
)
}
}
*/
// 函数式组件
function C() {
return (
<div className='grandchild'>
<div>C组件</div>
<div>从A组件接收到的用户名:
<Consumer>
{ value => `${value}` }
</Consumer>
</div>
</div>
)
}
/src/components/Demo/index.css
.parent{
width: 500px;
background-color: orange;
padding: 5px;
}
.child{
width: 400px;
background-color: skyblue;
padding: 5px;
}
.grandchild{
width: 300px;
background-color: red;
padding: 5px;
}
3.组件优化PureComponent
问题:只有当组件的state或props数据发生改变时,才重新render()。
原因:组件中的shouldComponentUpdate()总是返回true
解决:
①重写shouldComponentUpdate()方法,比较新旧state或props数据,有变化返回true,没有返回false
②使用PureComponent,PureComponent重写了shouldComponentUpdate(),只有state或props有变化才返回true,项目中一般使用PureComponent来优化。
4.