react的一些杂乱知识点

生命周期

组件从创建到销毁的一系列过程

挂载时阶段

  • contructor(props){super(props)}构造函数,只会触发一次
    • 初始化state
    • 给函数提前绑定this
    • 注意事项:1.必须写super()调用父类的构造函数,2.可以调用接口,但不推荐
  • static getDerivedStateFromProps(props,state)
    • 会触发多次,挂载与更新阶段都会触发
    • 触发在挂载阶段的constructor之后,render之前,DerivedState派生state
    • 参数:
      props:组件最新收到的props数据
      state:组件当前的state数据
    • 注意事项:
      1.该函数增加了static表示为类的函数,不能使用this
      2.该函数必须要有返回值,返回值的内容需要一个或者null
      返回对象:该对象会与当前的state合并,最终state中会包含该对象的内容
      返回null:不会合并操作
    • 使用场景:
      当前组件的数据, 需要基于props做更新时使用,类似于vue的计算属性
  • render()渲染函数,会触发多次,挂载阶段和更新阶段都会触发
    • 返回一段jsx来渲染页面
    • 注意事项:
      1.不能调用接口,保持组件的纯粹
      2.不能包含副作用的操作:操作DOM,改变数据,调用接口
  • componentDidMount()挂载完成,只会触发一次
    在这个钩子函数中可以:
    • 调用接口
    • 获取组件的真实DOM
    • 全局事件绑定,如:window.addEventlisten(‘scroll’)
    • 订阅,如:pubsubjs或者其他模块做事件总线
    • 计时器或定时器

更新时阶段

在new props,setState,forceUpdate时,就会进入更新阶段

  • static getDerivedStateFromProps(props,state)
  • shouldComponentUpdate(nextProps,nextState)
    • 在继承React.PureComponent的组件中不能写这个钩子函数,因为这个继承已经有了类似的该功能
    • 参数:
      nextProps:更新后的props,当需要用旧数据与新数据做比较时,this.props就是拿到老数据
      nextState:更新后的state
    • 用于做性能优化,控制组件是否需要更新需要有返回值,返回true需要更新,false不需要更新
    • 如果调用的是forceupdate()强制更新,该生命周期钩子函数不会触发
    • 如果组件继承的是PureComponent,则不要使用该生命周期
  • render()在上一步返回true需要更新时,进入该钩子函数,forceUpdate触发直接进入render
  • getSnapshotBeforeUpdate(prevProps,prevState),Snapshot快照
    • 在组件更新之前获取当前的真实DOM的快照信息
    • 参数:
      prevProps更新前的props
      prevState更新前的state
      需要返回值,返回值会作为componentDidUpdate()的第三个参数
  • componentDidUpdate(prevProps,prevState,snapshot)组件更新完成,真实DOM已经替换
    这里第三个参数就是getSnapshotBeforeUpdate()的返回值
    在这个钩子函数中,不要修改数据,调用接口,会导致死循环,要加上条件控制

卸载时阶段

  • componentWillUnmount(){
    收尾工作,解绑事件,解除定时器
    比如:eventBus.off(“要取消的事件名字”,对应的处理函数)
    }

Context 上下文,类似于vue的依赖注入(provide inject)

当组件层级非常深时,需要传值使用

  • 另起一个js文件,引入createContext
import { createContext } from "react";
const context = createContext();
export default context;
  • 在组件jsx文件中导入,
import Context from "./contexts/context";
  • 长辈组件中(父组件或爷组件等高层级的组件),使用Context.Provider
class App extends React.Component {
  state = {
    name: "张三",
  };
  render() {
    return (
    //通过value绑定state的数据传递给儿孙组件
      <Context.Provider value={this.state.name}>
        <h1>App</h1>
        <button
          onClick={() =>
            this.setState((prevState) => ({
              name: prevState.name + "~",
            }))
          }
        >
          修改我的 name,我后代通过 Context 获取到的值都会跟着变
        </button>
        <hr />
        <Hello />
      </Context.Provider>
    );
  }
}
  • 子组件以及孙子组件
//孙子组件
class Button extends React.Component {
  render() {
    return (
      <div>
        {/* 
          Consumer , 接受一个 函数类型的 children prop
              1. 函数会自动调用,且会接收到一个参数,参数值value就是配套的 Provider 的提供值。
        */}
        <Context.Consumer>
          {(value) => {
            return <button>Button - {value}</button>;
          }}
        </Context.Consumer>
      </div>
    );
  }
}
//子组件
class Hello extends React.Component {
  static contextType = Context;
  render() {
    return (
      <div>
        <h4>Hello - {this.context}</h4>
        <hr />
        //引入孙子组件Button
        <Button />
      </div>
    );
  }
}

类组件如何使用

1.需要通过React.createContext(defaultValue) 创建个context对象
该方法可以传递一个默认的value 的值
import { createContext } from “react”
const context = createContext(“张三”)
2.要使用的组件就直接引入该context 对象,且设置到类的contextType 属性上。
import Context from “./context”
App.contextType = Context 或在类中 static contextType = Context
3.该组件就可以通过this.context 获取到context对象的内容了。

这里创建的context是无法修改的,需要使用context的Provider组件

<context.Provider value={数据}>
<子组件>
</context.Provider>

context的Consumer组件

在子组件中
<Context.Consumer>
{(value)=>{
return {value}
}}
</Context.Consumer>
这组标签内的函数会自动执行,其中参数value就是长辈组件传下来的context.Provider的数据

猜你喜欢

转载自blog.csdn.net/q1553048604/article/details/130218458
今日推荐