是否存在强制React破坏和重构元素的非hacky方式?

时间:2017-02-10 22:38:26

标签: javascript reactjs

长话短说,我希望React创建一个全新的元素,而不是重用现有的元素。这样它再次运行构造函数。

默认情况下,React尝试尽可能多地重用。一个hacky解决方法是向元素添加key属性。例如:

class Foo extends React.Component {
  constructor() {
    super();

    this.state = {
      forceReloadCounter: 0,
    };
  }

  _forceReload() {
    this.setState({forceReloadCounter: this.state.forceReloadCounter + 1});
  }

  render() {
    return (
      <ChildElement key={this.state.forceReloadCounter}/>
    );
  }
}

如果_forceReload运行,则会更改ChildElement&#39; key,因此React会破坏ChildElement的旧实例并构建一个新实例。但是,这个解决方案显然非常hacky。阅读代码的任何人都会感到困惑。有更好的解决方案吗?

1 个答案:

答案 0 :(得分:1)

我写了一个以更干净的方式使用我的hacky解决方案的课程。

class RecreateChildOnPropsChange extends React.Component {
  constructor() {
    super();

    this._forceRecreateCounter = 0;
  }

  shouldComponentUpdate(nextProps) {
    assert(nextProps.children, 'Every props object should have childrens.');

    let props = this.props;
    if (props === nextProps) {
      return true;
    }

    let keys = Object.keys(props);
    let nextKeys = Object.keys(nextProps);

    if (keys.length !== nextKeys.length) {
      return false;
    }

    for (let key of keys) {
      if (key !== 'children' && (!nextProps.hasOwnProperty(key) || props[key] !== nextProps[key])) {
        return true;
      }
    }

    return false;
  }

  render() {
    this._forceRecreateCounter++;

    return React.cloneElement(
      React.Children.only(this.props.children),
      {key: this._forceRecreateCounter}
    );
  }
}

它会像这样使用:

<RecreateChildOnPropsChange startingPage={page}>
  <Newsfeed startingPage={page}/>
</RecreateChildOnPropsChange>

如果RecreateChildOnPropsChange的任何属性发生更改,它将销毁并重新创建其子元素。