React.js 不区分相同 class 的两个组件

React.js does not differentiate between two components of same class

不确定这是 React.js 错误还是 Javascript 语言的 "feature"。我有一个名为 Page 的 React.js (edit: using v0.12.x) 组件,它充当路由器并根据以下条件选择子组件路线。我创建了一个 mixin,它添加了一个名为 runRoute 的函数,它接受一个 JSX 组件并使用 PagesetState 方法来更新 state.routeComponent。此外,runRoute 还调用 forceUpdate() 以确保重新呈现 Page

问题 是 React 似乎不会区分状态相同的两个组件 class。我会解释。

我有两个子组件,名为 BoardProfileBoard 被重新用于不同的上下文。如果两个连续的路由是运行,即都使用<Board/>,React.js不会更新UI。只有当使用不同 class(例如 <Profile/>)的连续路由时,UI 才会实际更新。如果状态更改为另一条以不同方式使用 <Board/> 的路由,它只会将 UI 更新为 <Board/>.

的适当状态

下面是 <Page/> 和我的 Router mixin 的一些示例代码:

Router.js

module.exports = function(){
  return {

    getInitialState: function () {
      return {
        routeComponent: null
      };
    },

    runRoute: function(component){
      this.setState({routeComponent: component});
      this.forceUpdate();
    },

    componentWillMount: function() {
      var self = this;
      self.router = Router(self.routes).configure({
        resource: self, 
        notFound: self.notFound
      });
      self.router.init(); 
    }
  };
}

Page.jsx

module.exports = function(React, Router, NotFound, Profile, Board) {
  return React.createClass({

    mixins: [Router],

    routes: {
      '/board': 'trending',
      '/board/mostloved': 'mostLoved',
      '/profile': 'profile'
    },

    trending: function() {
      this.runRoute(
        <Board title="Trending Boards" setTitle={this.props.setTitle} />
      );
    },

    mostLoved: function() {
      this.runRoute(
        <Board title="Loved Boards" setTitle={this.props.setTitle} />
      );
    },

    profile: function() {
      this.runRoute(
        <Profile setTitle={this.props.setTitle} />
      );
    },

    notFound: function () {
      this.runRoute(
        <NotFound setTitle={this.props.setTitle} />
      );
    },

    render: function() {
      return this.state.routeComponent;
    }

  });
};

如果有人对此有所了解,我们将不胜感激。谢谢!

如果不查看您的 Board 组件就无法确定,但看起来问题在于它的状态取决于属性,并且当属性更新时(在runRoute).

这是演示问题的简单示例 (jsfiddle):

var Board = React.createClass({
  getInitialState: function() {
    return {title: this.props.title}
  },
  render: function() {
    return <h1>{this.state.title}</h1>
  }
});

var Page = React.createClass({
  getInitialState: function () {
    return {routeComponent: null}
  },

  handleClick: function(title) {
    var self = this;
    return function() {
      self.setState({ routeComponent: <Board title={title} /> })
    }
  },
  render: function() {
    return <div>
      <a href='#' onClick={this.handleClick('Trending')}>Trending</a>
      <br/>
      <a href='#' onClick={this.handleClick('Most Loved')}>Most Loved</a>
      {this.state.routeComponent}
    </div>;
  }
});

单击链接会更改 Page 的状态,但不会更改 Board 的视觉表示。

您需要通过处理 componentWillReceiveProps 中的更改来使 Board 的状态与其更新的属性保持同步。

只需向 Board 添加几行即可解决问题:

  componentWillReceiveProps: function(props) {
    this.setState({title: props.title})
  },

附带说明:您永远不需要在 this.setState() 之后立即使用 this.forceUpdate()。如果没有它就无法获得所需的行为,那是你做错了什么。