处理更改列数的子组件更新

时间:2017-03-04 16:13:08

标签: javascript reactjs ecmascript-6

我目前正在经历一个关于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);

1 个答案:

答案 0 :(得分:0)

看来,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)=&gt; {

var uri = new Uri("https://demo.com/");
                var encoding = new UTF8Encoding();
                var request = (HttpWebRequest)WebRequest.Create(uri);
                request.Method = "POST";

                request.Credentials = new NetworkCredential(utility.commonkey, utility.commonsecrerkey);
                request.ContentType = "application/json";
                request.Accept = "application/vnd.demo+json;version=3;";
                request.ContentLength = encoding.GetByteCount(json);
                request.Headers.Add("data", json);
                HttpWebResponse response = null;

}