【问题标题】:How to setState for array immediately?如何立即为数组设置状态?
【发布时间】:2017-04-03 06:21:58
【问题描述】:

我在 react 中遇到了一个与更新状态有关的问题。

嗯,我有一些数据,我想用这些数据构建一个表。但是,我想先过滤它。过滤效果很好,但我只有更新过滤数据并将其扔给下一个组件的问题......(我知道 setState 没有立即工作......)

ReportTable 组件中的updatedReports 仍然没有过滤数据... 修复它并使用更新数组状态的最佳方法是什么。

export default class ReportContent extends React.Component {

constructor(props) {
    super(props);
    this.state = {
        currentReports: this.props.reports
    };
}

_filterBy(option) {
    let updatedReports = [...this.props.reports].filter(report => {
        if (report.organizations === option || report.reportType === option) {
            return report;
        }
    });
    console.log(updatedReports);
    this.setState({currentReports: updatedReports});
}

render() {
    return (
        <div className="reports-table">
            <ReportMenu organizations={this.props.organizations} reportTypes={this.props.reportTypes}
                        filterBy={this._filterBy.bind(this)}/>
            <ReportTable updatedReports={this.state.currentReports}/>
        </div>
    );
}

}

【问题讨论】:

  • 除了_filterBy 方法中option 参数的结构之外,我没有看到代码有任何问题。你能发布你的ReportMenu 组件和option 参数的结构吗?
  • @jpdelatorre 选项参数很好......当我记录 updatedReports - 我得到了我想要的......问题是 currentReports 没有立即更新。

标签: arrays reactjs setstate


【解决方案1】:

您也许可以使用组件生命周期方法。 Here is more info.

componentDidMount 应该可以解决问题。你可以这样做:

componentDidMount(){
    let updatedReports = [...this.props.reports].filter(report => {
        if (report.organizations === option || report.reportType === option) {
            return report;
        }
    });
    this.setState({currentReports: updatedReports});
}

或者只是在componentDidMount中调用你的方法_filterBy

希望这会有所帮助。

【讨论】:

  • 我正在考虑它,但我不知道如何处理我从子组件获得的 'option' 参数...
  • 你能创作小提琴吗?
  • 很抱歉,那里的代码太多了...我不知道如何为相同情况提供一个简短而正确的示例..
【解决方案2】:

您提供的代码没有问题。如果调用正确,setState 应该可以工作。我敢打赌,问题出在您的其他组件或数据中。

这是一个使用您的代码的 sn-p。我不知道你是如何实现其他组件的,所以我只是在这里做了一些假设。

class ReportMenu extends React.Component {
    render() {
        return <div className="well well-default">
            <select className="form-control" onChange={(e) => {
                this.props.filterBy(e.target.value)
            }}>
                <option> - </option>
                {this.props.organizations.map(
                    (item, index) => <option key={index}>{item}</option>
                )}
            </select>
            <br/>
            <select className="form-control" onChange={(e) => {
                this.props.filterBy(e.target.value)
            }}>
                <option> - </option>
                {this.props.reportTypes.map(
                    (item, index) => <option key={index}>{item}</option>
                )}
            </select>
        </div>
    }
}

class ReportTable extends React.Component {
    render() {
        return <table className="table table-bordered">
            <tbody>
                {this.props.updatedReports.map(
                    (item, index) => <tr key={index}>
                        <td>{index}</td>
                        <td>{item.organizations}</td>
                        <td>{item.reportType}</td>
                    </tr>
                )}
            </tbody>
        </table>
    }
}

class ReportContent extends React.Component {
    constructor(props) {
        super(props);
        this.state = {
            currentReports: this.props.reports
        };
    }
    _filterBy(option) {
        let updatedReports = this.props.reports.filter(report => {
            if (report.organizations === option || report.reportType === option) {
                return report;
            }
        });
        console.log(updatedReports);
        this.setState({currentReports: updatedReports});
    }
    render() {
        return (
            <div className="reports-table">
                <ReportMenu 
                    organizations={this.props.organizations} 
                    reportTypes={this.props.reportTypes} 
                    filterBy={this._filterBy.bind(this)}/>
                <ReportTable updatedReports={this.state.currentReports}/>
            </div>
        );
    }
}

class App extends React.Component {
    render() {
        const reports = [
            {
                organizations: 'orgA',
                reportType: 'typeA'
            }, {
                organizations: 'orgA',
                reportType: 'typeB'
            }, {
                organizations: 'orgB',
                reportType: 'typeA'
            }, {
                organizations: 'orgB',
                reportType: 'typeB'
            }
        ];
        return <div className="container">
            <h1 className="page-header">Reports</h1>
            <ReportContent 
                reports={reports} 
                organizations={['orgA', 'orgB']} 
                reportTypes={['typeA', 'typeB']}/>
        </div>
    }
}

ReactDOM.render(<App/>, document.getElementById('root'));

【讨论】:

  • 你是对的!我的 ReportTable 组件中有额外的状态......现在传递的道具是正确的......但我知道我还有另一个问题:Uncaught NotFoundError: Failed to execute 'removeChild' on 'Node': The node to be removed is not a child of this node.
  • 该问题需要更多信息才能弄清楚,并且与您最初的问题完全不同。将此问题标记为已回答并发布另一个包含更多详细信息的问题可能是个好主意。
猜你喜欢
  • 2017-03-30
  • 2022-11-29
  • 1970-01-01
  • 1970-01-01
  • 2017-11-17
  • 1970-01-01
  • 2017-08-17
  • 1970-01-01
  • 2019-11-15
相关资源
最近更新 更多