React

React 状态复用

By John Han
Picture of the author
Published on
image alt attribute

React 状态复用

1. React 组件之间如何进行状态复用?

ReactFunction Component 是没有状态的,因此也叫做无状态组件

ReactClass Component 是有状态的。

创建一个有状态的 Class Component:

import { Component } from "react";

class ComponentA extends Component {
  // 定义状态
  state = {
    num: 1,
  };

  render() {
    // 使用状态
    return <div>Num{this.state.num}</div>;
  }
}

export default ComponentA;

假如现在有一个需求,要在组件 ComponentB 中使用 ComponentA 的状态“num”,怎么办 ❓

此时你可能会想到两个常见方法:

1.1 使用 render props 传递 state

React RouterDownshift 以及 Formik 等都使用了 render prop。

创建组件 B

class ComponentB extends Component {
  render() {
    // 接收 props 传递的 num
    const num = this.props.num;
    return <div>My Num is {num}.</div>;
  }
}

修改组件 A,动态渲染内容

class ComponentA extends Component {
  // 定义状态
  state = {
    num: 1,
  };

  render() {
    // 使用状态
    return (
      <div>
        {/*
          使用 `render`prop 动态决定要渲染的内容,
          而不是给出一个 <ComponentA> 渲染结果的静态表示
        */}
        {this.props.renderProp(this.state)}
      </div>
    );
  }
}

把组件 B 通过 render 传递给组件 A:

class Container extends Component {
  render() {
    return (
      <div>
        <p>test</p>
        <ComponentA renderProp={(num) => <ComponentB num={num} />}></ComponentA>
      <div/>
    );
  }
}

render prop 方法的原理

提供状态的组件(ComponentA)通过函数作为prop动态渲染使用状态的组件(ComponentB)。

1.2 使用 高阶组件(HOC)传递 state

function ppHOC(WrappedComponent) {
  return class PP extends React.Component {
    constructor(props) {
      super(props);
      this.state = {
        name: "",
      };

      this.onNameChange = this.onNameChange.bind(this);
    }
    onNameChange(event) {
      this.setState({
        name: event.target.value,
      });
    }
    render() {
      const newProps = {
        name: {
          value: this.state.name,
          onChange: this.onNameChange,
        },
      };
      return <WrappedComponent {...this.props} {...newProps} />;
    }
  };
}

使用 ppHOC:

@ppHOC
class Example extends React.Component {
  render() {
    return <input name="name" {...this.props.name} />;
  }
}

1.3 使用自定义 Hook

Stay Tuned

Want to become a Next.js pro?
The best articles, links and news related to web development delivered once a week to your inbox.