React 高阶组件(8)

高阶组件

High Order Component

  1. HOC 是一种高级的设计模式
  2. HOC 是一个函数,接收一个组件参数,返回一个新组件
  3. 普通组件返回的是 UIHOC 返回的是一个新组件
  4. HOC 不能修改参数组件,只能传入组件所需的 props
  5. HOC 是一个没有副作用的纯函数
  6. HOC 除了必须填入被包裹的组件参数外,其他参数根据需求增加
  7. HOC 不关心数据如何使用,包裹组件不关心数据从哪里来
  8. HOC 和包裹组件唯一直接的契合点就是 props

HOC 更加关注逻辑和状态的管理,参数组件的逻辑与状态订阅;
参数组件基本只需关注视图的渲染;

function fetchListData(field) {
  return new Promise((resolve, reject) => {
    resolve({
      data: [
        {
          name: "zs",
          age: 12,
          score: 44,
        },
        {
          name: "ls",
          age: 12,
          score: 44,
        },
        {
          name: "ww",
          age: 12,
          score: 44,
        },
      ],
    });
  });
}

function listHoc(WrapperComponent, fetchListData) {
  return class extends React.Component {
    state = {
      listData: [],
    };
    async componentDidMount() {
      const result = await fetchListData(this.props.field);

      this.setState({
        listData: result.data,
      });
    }

    removeStd(name) {
      this.setState({
        listData: this.state.listData.filter((item) => item.name !== name),
      });
    }

    render() {
      return (
        <WrapperComponent
          data={this.state.listData}
          removeStd={this.removeStd.bind(this)}
        />
      );
    }
  };
}

class StudentList extends React.Component {
  render() {
    return (
      <table border="1">
        <thead>
          <tr>
            <th>Name</th>
            <th>Age</th>
            <th>Score</th>
            <th>操作</th>
          </tr>
        </thead>
        <tbody>
          {this.props.data.map((item, index) => (
            <tr>
              <td>{item.name}</td>
              <td>{item.age}</td>
              <td>{item.score}</td>
              <td onClick={() => this.props.removeStd(item.name)}>删除</td>
            </tr>
          ))}
        </tbody>
      </table>
    );
  }
}

const StudentListHoc = listHoc(StudentList, fetchListData);

class App extends React.Component {
  render() {
    return <StudentListHoc field="student" />;
  }
}

ReactDOM.render(<App />, document.querySelector("#app"));
function InputHoc(WrapperComp) {
  // 会导致原组件声明周期中对应的函数不会执行,相当于重写
  // 不能这样修改,可能会导致组件内部的逻辑失效
  // WrapperComp.prototype.componentDidUpdate = function () {
  //   console.log("Input Hoc1");
  // };

  class InputComponent extends React.Component {
    state = {
      value: "",
    };
    // 这里和上面的重写不冲突
    // 可以在这里重写函数,与原组件内部逻辑不冲突,用作对原组件逻辑的扩展
    componentDidUpdate() {
      console.log("Input Hoc2");
    }

    chgInput(e) {
      this.setState({
        value: e.target.value,
      });
    }
    render() {
      const { a, ...props } = this.props;

      return (
        <WrapperComp
          value={this.state.value}
          chgInput={this.chgInput.bind(this)}
          {...props}
        />
      );
    }
  }
  // 可以改变别名
  InputComponent.displayName = "InputHoc";

  return InputComponent;
}

class MyInput extends React.Component {
  componentDidUpdate() {
    console.log("MyInput");
  }

  render() {
    return (
      <div>
        <p>总计:{this.props.b + this.props.c}</p>
        <p>
          <input
            type="text"
            defaultValue={this.props.value}
            onChange={this.props.chgInput}
          />
        </p>
        <p>{this.props.value}</p>
      </div>
    );
  }
}

const MyInputHoc = InputHoc(MyInput);

class App extends React.Component {
  state = {
    a: 1,
    b: 2,
    c: 3,
  };

  render() {
    return <MyInputHoc {...this.state} />;
  }
}
ReactDOM.render(<App />, document.querySelector("#app"));
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值