跳到正文
当下的七炎
返回

react16新特性

编辑文章

废弃了一些Api

componentWillReceiveProps componentWillMount componentWillUpdate

增加了一些Api

static getDerivedStateFromProps(props, state)

// 判断props的东西和state是不是一样,来确定是不是用props来更新state
// 这种要少用,反模式
// 返回的就是state
// ep:
// return {
//     list:[]
// }
//等同于componentWillReceiveProps中
// this.setState({
//     list:[]
// })
// Derive --从什么中得到,派生的

getSnapshotBeforeUpdate

getSnapshotBeforeUpdate(prevProps, prevState) {
    console.log("children2.getSnapshotBeforeUpdate");
    // 这个生命周期会在componentDidUpdate之前,并将返回值传递给下一个生命周期
    return "11";
  }
  componentDidUpdate(prevProps, prevState, snapshot) {
    console.log("children2.componentDidUpdate", snapshot); //11
  }

ref绑定

this.div1 = React.createRef();
<div ref={this.div1} />

//这里用得时候需要 this.div1.current 相当于以前得写法

context工作流程

1.需要些一个Provider 2.用Provider包裹一个顶层组件

function ProviderApp() {
  return (
    <TodoProvider>
      <App />
    </TodoProvider>
  );
}

3.其他的子组件可以用Consumer或者contextType和Provider连接起来 TodoProvider.js

import React, { Component } from "react";

export const TodoContext = React.createContext();

// 这里的Provider类似于dva的model

export class TodoProvider extends Component {
  constructor(props) {
    super(props);
    this.state = {
      todoList: [
        {
          text: "1111111"
        }
      ]
    };
  }
  add = value => {
    let { todoList } = this.state;
    let nlist = [...todoList, { text: value }];
    this.setState({
      todoList: nlist
    });
  };
  render() {
    return (
      <TodoContext.Provider value={{ cxt: this.state, add: this.add }}>
        {this.props.children}
      </TodoContext.Provider>
    );
  }
}

App.js

import React, { Component } from "react";
import "./App.css";
import Box from "./Box";
import List from "./List";
import List2 from "./List2";
import { TodoContext, TodoProvider } from "./TodoProvider";

class Content extends Component {
  constructor(props) {
    super(props);
    this.state = {
      value: ""
    };
  }
  handleInputChange = e => {
    let value = e.target.value;
    this.setState({
      value: value
    });
  };
  componentWillMount() {
    console.log("app.componentWillMount");
  }
  componentDidMount() {
    console.log("app.componentDidMount");
  }
  render() {
    console.log("app.props", this.props); // 有数据
    console.log("app.context", this.context);
    let { cxt } = this.props;
    let { todoList } = cxt;
    todoList = todoList || [];
    let { value } = this.state;
    return (
      <div className="App">
        <h1>todo</h1>
        <input type="text" value={value} onChange={this.handleInputChange} />
        <button onClick={() => this.props.add(value)}> 添加</button>
        <ul>
          {todoList.map((t, index) => {
            return <li key={JSON.stringify(t)}>{t.text}</li>;
          })}
        </ul>
        <Box />
        <List />
        <List2 />
      </div>
    );
  }
}
function App() {
  return (
    <div>
      <TodoContext.Consumer>{ctx => <Content {...ctx} />}</TodoContext.Consumer>
    </div>
  );
}
function ProviderApp() {
  return (
    <TodoProvider>
      <App />
    </TodoProvider>
  );
}
export default ProviderApp;

Box.js

import React, { Component } from "react";
import { TodoContext } from "./TodoProvider";
//contextType用法
class Box extends Component {
  async componentWillMount() {
    console.log("children1.box.componentWillMount");
    await new Promise(resolve => {
      setTimeout(() => {
        resolve(1);
      }, 2000);
    });

    console.log("Promise");
  }
  componentDidMount() {
    console.log("children1.box.componentDidMount");
  }
  render() {
    console.log("children1.box.props", this.props);
    console.log("children1.box.context", this.context); //有数据
    return <div />;
  }
}
Box.contextType = TodoContext;
export default Box;
//contextType仅支持类的组件

// 既然数据放在context里面,我们应该多使用纯函数组件 // Consumer 使用注意 // 1.纯函数的 2.多个context的 List2.js

import React, { Component } from "react";
import { TodoContext } from "./TodoProvider";
function List2() {
  return (
    <TodoContext.Consumer>
      {({ cxt }) => (
        <div>
          <h2>List2</h2>
          {JSON.stringify(cxt)}
        </div>
      )}
    </TodoContext.Consumer>
  );
}
export default List2;

List3 hooks的写法

import React from "react";
import { useContext } from "react";
import { TodoContext } from "./TodoProvider";
function List3() {
  const context = useContext(TodoContext);
  console.log("List3.context", context);
  //List3.context
  //Object {cxt: Object, add: function ()}

  return <div>useContext</div>;
}
export default List3;

下面是context的流程图

image

比较符合react思想,组件包裹,传方法和数据下来

组件延迟加载

import React, {lazy, Suspense} from "react"
const UploadLocalImg= lazy(() => import("../UploadLocalImg")

<Suspense fallback = {<div> Loading...</div>} >
       <UploadLocalImg />
</Suspense>
// 需要搭配Suspense 使用,并且依赖 @babel/plugin-syntax-dynamic-import fixed 

代码地址 https://codesandbox.io/embed/react-context-exemple-lbcks

参考链接

context React@16.3 全新的Context API进阶教程


编辑文章
分享这篇文章:

评论

使用 GitHub 账号登录后即可评论


上一篇
react-redux工作流程
下一篇
new操作符做了什么?