4.1 初识高阶组件
- ⾼阶组件—HOC(Higher-Order Components)
- ⾼阶组件是为了提⾼组件的复⽤率⽽出现的,抽离出具有相同逻辑或相同展示的组件
- ⾼阶组件其实是⼀个函数,接收⼀个组件,然后返回⼀个新的组件,返回的这个新的组件可以对属性进⾏包装,也可以重写部分⽣命周期
app.js
import React, { Component } from 'react'
const withLearnReact = Comp => {
const NewCompnent = props => {
//{...props}继承原来组件的属性,title属性
//新组件加了name属性
return <Comp {...props} name="newAttributeName"></Comp>
}
return NewCompnent
}
class App extends Component {
render() {
return (
<div>
<h1>高阶组件</h1>
<p>原来的title属性:{this.props.title}</p>
<p>name属性:{this.props.name}</p>
</div>
)
}
}
export default withLearnReact(App)
index.js
import React from 'react'
import ReactDOM from 'react-dom'
import './index.css'
import App from './App';
import * as serviceWorker from './serviceWorker'
ReactDOM.render(
<App title="我是title属性" />,
document.getElementById('root')
)
serviceWorker.unregister()
4.2 ⾼阶组件的链式调⽤
- 编写⼀个⾼阶组件进⾏属性的添加
- 编写⼀个⾼阶组件编写⽣命周期
- 然后将以上两个⾼阶组件进⾏链式调⽤
App.js
import React, { Component } from 'react'
//第一个高阶组件,添加属性
const withLearnReact = Comp => {
const NewCompnent = props => {
//{...props}继承原来组件的属性,title属性
//新组件加了name属性
return <Comp {...props} name="newAttributeName"></Comp>
}
return NewCompnent
}
//第二个高阶组件,重写生命周期
const withLifeCycle=Comp=>{
class NewCompnent extends Component{
componentDidMount(){
console.log('重写ComponentDidMount生命周期')
}
render(){
return <Comp {...this.props}></Comp>
}
}
return NewCompnent
}
class App extends Component {
render() {
return (
<div>
<h1>高阶组件</h1>
<p>原来的title属性:{this.props.title}</p>
<p>name属性:{this.props.name}</p>
</div>
)
}
}
export default withLifeCycle(withLearnReact(App))
4.3 ⾼阶组件装饰器
上面的最后一行,是不是让你很懵
export default withLifeCycle(withLearnReact(App))
我们可以不用链式调用,改用装饰器
用装饰器前期准备工作
将上面的链式调用的代码改用装饰器
App.js
import React, { Component } from 'react'
//第一个高阶组件,添加属性
const withLearnReact = Comp => {
const NewCompnent = props => {
//{...props}继承原来组件的属性,title属性
//新组件加了name属性
return <Comp {...props} name="newAttributeName"></Comp>
}
return NewCompnent
}
//第二个高阶组件,重写生命周期
const withLifeCycle = Comp => {
class NewCompnent extends Component {
componentDidMount() {
console.log('重写ComponentDidMount生命周期')
}
render() {
return <Comp {...this.props}></Comp>
}
}
return NewCompnent
}
@withLearnReact
@withLifeCycle
class App extends Component {
render() {
return (
<div>
<h1>高阶组件</h1>
<p>原来的title属性:{this.props.title}</p>
<p>name属性:{this.props.name}</p>
</div>
)
}
}
export default App
4.4 组件通信之上下⽂(context)
- 上下⽂context有两个⻆⾊
Provider 数据提供
Consumer 数据读取 - 使⽤context可以避免通过中间元素传递props,context的设计⽬ 的是为了共享对于⼀个组件树⽽⾔是“全局”的数据
- 不使⽤context的情况下的代码:
App.js
import React, { Component } from 'react'
let store={
name:'uncleHuang',
sex:'女'
}
class Info extends Component{
render(){
return(
<div>
<p>姓名:{this.props.name}</p>
<p>性别:{this.props.sex}</p>
</div>
)
}
}
function ToolBar(props){
return(
<div>
<Info {...props}></Info>
</div>
)
}
class App extends Component {
render() {
return (
<div>
<h1>高阶组件上下文通信使用前</h1>
<ToolBar name={store.name} sex={store.sex}></ToolBar>
</div>
)
}
}
export default App
- 使⽤context,避免了中间props元素的传递的写法
App.js
import React, { Component } from 'react'
//创建上下文
const HahaContext=React.createContext()
const {Provider,Consumer}=HahaContext
let store={
name:'uncleHuang',
sex:'女'
}
class Info extends Component{
render(){
return(
<Consumer>
{
store=>{
return(
<div>
<p>姓名:{store.name}</p>
<p>性别:{store.sex}</p>
</div>
)
}
}
</Consumer>
)
}
}
function ToolBar(props){
return(
<div>
<Info></Info>
</div>
)
}
class App extends Component {
render() {
return (
<div>
<h1>高阶组件上下文通信使用后</h1>
<Provider value={store}>
<ToolBar></ToolBar>
</Provider>
</div>
)
}
}
export default App