从HOC和组件中反应状态

时间:2017-01-05 23:27:11

标签: reactjs jsx higher-order-components

我有一个通过高阶组件管理受控输入的表单。结构是这样的:

字段高阶组件

function BaseField(WrappedComponent) {
  class WrappedField extends React.Component {
    constructor(props) {
      super(props);
      this.state = {
        value: '',
        active: false,
      }
    }

    setValue = (e) => {
      this.setState({ value: e.target.value })
    }
    ...
    <WrappedComponent
      {...this.props}
      value={this.state.value}
      set={this.setValue}
      active={this.state.active}
    />
    ....

字段

import React from 'react';
import BaseField from './BaseField';

const TextField = (props) => {
  return <input
    value={props.value}
    onChange={props.set}
    name={props.name}
    type={props.type}
  />
}

export default BaseField(TextField);

使用TextField时效果很好 - 但是,我想更灵活地使用它 - 例如,我希望能够在某些情况下增强onChange功能,总是让它设置状态,但让它根据TextField中使用的组件中的状态或函数执行其他操作。

我是否误解了HOC的工作原理?

1 个答案:

答案 0 :(得分:1)

您可以使用createChainedFunction中的react-bootstrap

function createChainedFunction(...funcs) {
  return funcs
    .filter(f => f != null)
    .reduce((acc, f) => {
      if (typeof f !== 'function') {
        throw new Error('Invalid Argument Type, must only provide functions, undefined, or null.');
      }

      if (acc === null) {
        return f;
      }

      return function chainedFunction(...args) {
        acc.apply(this, args);
        f.apply(this, args);
      };
    }, null);
}

来自我的react utils:

export function copyPropsWithout(props, without) {
  const propKeys = Object.keys(props);
  const passProps = propKeys.reduce((obj, propKey) => {
    if (without.indexOf(propKey) === -1) {
      obj[propKey] = props[propKey];
    }

    return obj;
  }, {});

  return passProps;
}

我将这些添加到您的工具中,然后使用它们:

 ...
    <WrappedComponent
      {...copyPropsWithout(this.props, ['onChange'])}
      value={this.state.value}
      set={createChainedFunction(this.setValue, this.props.onChange}}
      active={this.state.active}
    />
    ....