React 实用进阶合集(1)

375 阅读2分钟

1、函数组件和class组件为什么会被区分开 ?

  • 概述部分 需要学习哪些东西 image.png

image.png

  • 函数组件 为啥叫无状态组件 ? image.png

  • 函数组件 总结一下 ?

  • 为什么 称之为 class 简化部分 (当然函数组件功能可扩展)

image.png

2、 React非受控组件 ?

  • 在哪使用 ?

image.png

  • 举个例子
import React, { Component } from "react";

class UpFiles extends Component {
  constructor(props) {
    super(props);
    this.state = {};
    this.fileInputRef = React.createRef();
  }
  alertName = () => {
    const elem = this.fileInputRef.current;
    alert(elem.files[0].name);
  };
  render() {
    return (
      <div>
        <input type="file" ref={this.fileInputRef} />
        <button onClick={this.alertName}>alert name</button>
      </div>
    );
  }
}

export default UpFiles;


  • 实现效果
  • 非常nice 选择 文件可打印出 名字

image.png

3、React Portals 在哪使用 ?

  • 怎么使用这个 传送门 ?

image.png

image.png

  • 举个例子 说明这个情况 fixed 放在body第一层(root外层)

1、先常规来写 不使用 portals

  • PortalsDemo.js
import React, { Component } from "react";
import ReactDOM from "react-dom";
class PortalsDemo extends Component {
  constructor(props) {
    super(props);
    this.state = {};
  }
  render() {
    return (
      <div
        style={{
          position: "fixed",
          left: "300px",
          top: "300px",
          width: "200px",
          height: "200px",
          backgroundColor: "pink",
        }}
      >
        {this.props.children}
      </div>
    );
  }
}

export default PortalsDemo;

  • index.js fixed 内容区域

  • 页面效果 在 root内

image.png

2、使用 portals 试试

import React, { Component } from "react";
import ReactDOM from "react-dom";
class PortalsDemo extends Component {
  constructor(props) {
    super(props);
    this.state = {};
  }
  render() {
    // return (
    //   <div
    //     style={{
    //       position: "fixed",
    //       left: "300px",
    //       top: "300px",
    //       width: "200px",
    //       height: "200px",
    //       backgroundColor: "pink",
    //     }}
    //   >
    //     {this.props.children}
    //   </div>
    // );

    //使用 portals 放在body上 root外
    return ReactDOM.createPortal(
      <div
        style={{
          position: "fixed",
          left: "300px",
          top: "300px",
          backgroundColor: "pink",
        }}
      >
        {this.props.children}
      </div>,
      document.body
    );
  }
}

export default PortalsDemo;

  • 查看当前页面结构 明显可以看到逃离了 id='root'

image.png

4、React Context ?

image.png

  • 使用步骤
1、使用 React.createContext 创建context 并写默认值
2、使用 ThemeContext.Provider 包裹需要使用数据的子组件 并传值 value={this.state.theme}
3、函数组件使用 ThemeContext.Consumer 消费数据 
4class子组件 消费数据先定义 contextType 然后取值 this.context
5、完成多层级传递 
  • 层级展示

image.png

  • 完整代码展示
import React, { Component } from "react";

//创建context  并传入默认值
const ThemeContext = React.createContext("light");

// 函数组件使用 ThemeContext.Consumer 消费数据
function ThemeLink(props) {
  return (
    <ThemeContext.Consumer>
      {(value) => <p>link's theme is {value}</p>}
    </ThemeContext.Consumer>
  );
}

// class子组件 消费数据先定义 contextType 然后取值 this.context
class ThemeButton extends Component {
  constructor(props) {
    super(props);
    this.state = {};
  }
  render() {
    const theme = this.context;
    return (
      <div>
        <p>button's theme is {theme}</p>
      </div>
    );
  }
}
ThemeButton.contextType = ThemeContext;

function Tooolbar() {
  return (
    <div>
      <ThemeButton />
      <ThemeLink />
    </div>
  );
}
class Context extends Component {
  constructor(props) {
    super(props);
    this.state = {
      theme: "light",
    };
  }
  changeTheme = () => {
    this.setState({
      theme: this.state.theme === "light" ? "dark" : "light",
    });
  };
  render() {
    return (
      <ThemeContext.Provider value={this.state.theme}>
        <Tooolbar />
        <hr />
        <button onClick={this.changeTheme}>change the theme</button>
      </ThemeContext.Provider>
    );
  }
}

export default Context;

  • 页面效果展示 点击按钮 theme变化

image.png

image.png

  • 非常nice !

image.png