首页 > 解决方案 > 反应组件没有重新渲染,尽管道具中的对象发生了变化

问题描述

我知道,有很多很多类似的问题.. **重复警报!**

但是:我保证,我看过所有这些。我现在很确定,这是另一种情况,这可能与道具是一个对象有关(从我在这里读到的内容)。但无论如何我无法解决以下问题:

class CsvListDropdown extends Component {
    constructor(props) {
        super(props);
        this.state = { sessions: props.sessions }
        this csvsInSession = this.csvsInSession.bind(this);
    }

    csvsInSession(sessions) {
        return (sessions
            .map(keys => Object.entries(keys)[2][1])
            .map((csv, i) => (
                <option value={csv} key={i}>{csv}</option>
            ))
        )
    }

    render() {
        const { isLoading } = this.props
        if (isLoading) { blablabla.. }
        else {
            return (
                ...
                <select value={this.props.sessions[0].currentCsv}>
                    {this.csvsInSession(this.state.sessions)}
                </select>
                ...
            )
        }
    }
}

export default withTracker(() => {
    const handle = Meteor.subscribe('sessions');
    return {
      isLoading: !handle.ready(),
      sessions: Sessions.find({}).fetch() 
    };
})(CsvListDropdown);

现在,我正在从客户端将另一个文档写入Sessions集合,其中包含 .csv 文件名,而这个新的 csv 文件正在上传到远程服务器。console.log(this.props.sessions)给了我一个最新的数组。但是组件本身不会重新渲染。

我也不明白的是:console.log(this.state.sessions)returns undefined。(注:状态

到目前为止我尝试了什么:

同样重要的是:组件应该重新渲染大约在另一个组件也重新渲染的同时(它显示上传的 CSV 的内容,从微服务返回并写入另一个集合)。后者实际上确实重新渲染..但该下拉菜单没有..啊!

标签: javascriptreactjsmeteor

解决方案


this.state只有当你打电话时才会改变this.setState(),你没有这样做。您正在state使用 from 的值进行初始化props,但仅在首次实例化组件时在构造函数中进行。之后,即使props您的组件发生更改,您的组件可能会重新渲染,但它显示的内容不会更改,因为state尚未更新。

事实上,似乎没有任何理由将数据以状态存储在该组件中。它也可能是一个功能性的表示组件:

function CsvListDropdown(props) {
    function csvsInSession(sessions) {
        return (sessions
            .map(keys => Object.entries(keys)[2][1])
            .map((csv, i) => (
                <option value={csv} key={i}>{csv}</option>
            ))
        )
    }

    const { isLoading } = props;
    if (isLoading) { blablabla.. }
    else {
        return (
            ...
            <select>
                {csvsInSession(props.sessions)}
            <select>
            ...
        )
    }
}

通常,您的所有组件都应该是无状态的功能组件,除非它们出于某种原因特别需要存储内部状态。


推荐阅读