首页 > 解决方案 > React - 父组件更改时更新子组件中的状态

问题描述

我有一个包含两个反应组件的简单应用程序:

  1. vacancies.jsx - 列出空缺职位
  2. counter.jsx - 显示来自 vacancies.jsx 的空缺数量

当应用程序加载时,计数器显示正确的空缺数量,但是当我开始在 vacancies.jsx 中添加/删除空缺时,计数保持不变。

职位空缺.jsx:

export class Vacancy extends React.Component {

    constructor(props) {

        super(props);

        this.state = { vacancies: [], loading: true, title:"" };

        fetch('/api/Vacancy/Vacancies')
            .then(response => response.json())
            .then(data => {
                this.setState({ vacancies: data, loading: false });
            });
    }

    delete(id) {

        var vacancies = this.state.vacancies;

        this.setState(
            {
                vacancies: this.state.vacancies.filter((v) => {
                    return (v.id != id);
                })
            });

    }

    loadVacancies(vacancies) {
        return (
            <table className='table table-striped'>
                <thead>
                    <tr>
                        <th>Title</th>
                        <th>Min Salary</th>
                        <th>Max Salary</th>
                    </tr>
                </thead>
                <tbody>
                    {vacancies.map(v =>
                        <tr key={v.id}>
                            <td>{v.title}</td>
                            <td>{v.currency} {v.minSalary}</td>
                            <td>{v.currency} {v.maxSalary}</td>
                            <td>
                                <a href="#" onClick={(id) => this.delete(v.id)}>Delete</a>
                            </td>
                        </tr>
                    )}
                </tbody>
            </table>
        );
    }

    render() {

        let contents = this.state.loading
            ? <p><em>Loading...</em></p>
            : this.loadVacancies(this.state.vacancies);

        return (
            <div>
                {contents}
            </div>
        );
    }
}

const containerElement = document.getElementById('content');
ReactDOM.render(<Vacancy />, containerElement);

计数器.jsx

import { Vacancy } from "./vacancies";

export class Counter extends Vacancy {

    constructor(props) {

        super(props);
    }

    render() {

        return (
            <div>
                <h1>Items:{this.state.vacancies.length}</h1>
            </div>
        );
    }
}

ReactDOM.render(<Counter />, document.getElementById('counter'));

用户界面: 在此处输入图像描述

标签: javascriptasp.net-mvcreactjsreact-nativeasp.net-core

解决方案


根据 React 团队的说法,他们建议使用组合而不是继承:

React 具有强大的组合模型,我们建议使用组合而不是继承来重用组件之间的代码。

在 Facebook,我们在数以千计的组件中使用 React,我们还没有发现任何建议创建组件继承层次结构的用例。

https://reactjs.org/docs/composition-vs-inheritance.html

因此,根据您的代码,重新创建您的Counter组件,如下所示:

export const Counter = props => {
    return (
        <div>Items: {props.items}</div>
    );
};

然后只需更改您的Vacancies组件,包括您的新Counter组件:

loadVacancies(vacancies) {
    return (

        <Counter items={this.state.vacancies.length} />

        <table className='table table-striped'>
            <thead>
                <tr>
                    <th>Title</th>
                    <th>Min Salary</th>
                    <th>Max Salary</th>
                </tr>
            </thead>
            <tbody>
                {vacancies.map(v =>
                    <tr key={v.id}>
                        <td>{v.title}</td>
                        <td>{v.currency} {v.minSalary}</td>
                        <td>{v.currency} {v.maxSalary}</td>
                        <td>
                            <a href="#" onClick={(id) => this.delete(v.id)}>Delete</a>
                        </td>
                    </tr>
                )}
            </tbody>
        </table>
    );
}

推荐阅读