【问题标题】:Handle child component update of changing column count处理更改列数的子组件更新
【发布时间】:2017-03-04 16:13:07
【问题描述】:

我目前正在体验有关 Reactjs 的知识湖。我有一个由列组成的组件。列数是可变的(用户可以更改)。在此列中,有一些项目包含 youtube 嵌入视频。

当我更改列数时,父元素正在刷新并且子组件正在更新:视频播放器被刷新(因此视频被暂停并寻找到 0)。
我希望有一个系统能够在我更改列数时让我的孩子保持不更新。
我想,当我更改列数时,React 会重用一些可用的子组件并通过其他子组件更改它们的道具。因为有时视频不会中断。

子组件

export default class Article extends Component {

    static propTypes = {
        visible: React.PropTypes.bool.isRequired,
        title: React.PropTypes.string.isRequired,
        link: React.PropTypes.string.isRequired,
        userId: React.PropTypes.number.isRequired,
        contentId: React.PropTypes.number.isRequired,
        typeId: React.PropTypes.number.isRequired,
        typeName: React.PropTypes.string.isRequired,
        date: React.PropTypes.number.isRequired,
        username: React.PropTypes.string.isRequired,
        description: React.PropTypes.string,
        imageUrl: React.PropTypes.string
    };

    shouldComponentUpdate(nextProps) {
        return nextProps.link !== this.props.link;
    }

    render() { ... }

}

父组件

class Home extends UserComponent {

  static propTypes = {
    mode: React.PropTypes.number.isRequired,
    columnCount: React.PropTypes.number.isRequired,
    userList: React.PropTypes.array.isRequired,
  };

  state = {
    contents: [],
    columnCount: 0,
    userList: [],
  }

  ...

  renderArticles = (columnCount, columnNumber) => {
    if (this.state.contents.length > 0)
      return this.state.contents.map((content, key) => {
        if ((key + columnNumber) % columnCount !== 0) return null;
        let username = 'unknown';
        let typeName = 'unknown';

        this.state.userList.forEach((user) => {
          if (user.userId === content.userId) username = user.username;
        })

        const types = Type.getTypes();
        if (types) {
          types.forEach((type) => {
            if (content.typeId === type.id) typeName = type.name;
          })
        }
        return (
          <Article
            key={content.id}
            visible={true}
            title={content.title}
            link={content.link}
            userId={content.userId}
            typeId={content.typeId}
            contentId={content.id}
            date={content.date}
            description={content.description}
            imageUrl={content.imageUrl}
            username={username}
            typeName={typeName}
          />
        );
      });
    else
      return null;
  }

  render() {
    const { columnCount } = this.props.columnCount === 0 ? this.state : this.props;
    const containers = [];
    var i = 0;
    do {
      containers.push(
        <div key={i} className={styles.containers}>
          {this.renderArticles(columnCount, i)}
        </div>
      );
      i++;
    } while (i < columnCount);

    return (
      <div className={styles.container}>
        {containers}
      </div>
    );
  }
}

function mapStateToProps(state) {
  return {
    columnCount: state.articleColumnFilter.columnCount
  };
}

function mapDispatchToProps(dispatch) {
  return bindActionCreators(articleColumnActions, dispatch);
}

export default connect(mapStateToProps, mapDispatchToProps)(Home);

【问题讨论】:

  • shouldComponentUpdate 会被解雇吗?
  • @ArshabhAgarwal 在一些孩子身上,是的。我已经放弃了这个功能,我把视频播放器放到了一个弹出窗口中(比如 youtube android 应用程序)。

标签: javascript reactjs ecmascript-6


【解决方案1】:

看来,key={content.id} 在您之前呈现的同一列中不断变化。键在父项中必须是唯一的,并且不应针对您之前呈现的同一项目而更改。

https://facebook.github.io/react/docs/lists-and-keys.html#keys https://facebook.github.io/react/docs/reconciliation.html

renderArticles = (columnCount, columnNumber) => {

    return (
      <Article
        key={content.id}
        ...
        contentId={content.id}
        ...
      />
    );
  });
else
  return null;

}

【讨论】:

    猜你喜欢
    • 2016-01-22
    • 1970-01-01
    • 2021-06-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-07-24
    • 1970-01-01
    相关资源
    最近更新 更多