javascript - React - 父组件更改时更新子组件中的状态
问题描述
我有一个包含两个反应组件的简单应用程序:
- vacancies.jsx - 列出空缺职位
- 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'));
解决方案
根据 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>
);
}
推荐阅读
- javascript - 如何在 Ember js 3.13 中正确处理按键事件
- c# - 每个 GCode 图像的 Windows 文件资源管理器预览 C#
- python - Pandas 根据条件获取行 ID
- flutter - 如何根据颤动中TextField中的输入填充下拉列表?
- java - JPA 继承:MappedSuperclass 还是加入?
- sql - 需要按数据集中的值对第一列进行排序,然后找到平均值
- function - 在 Julia 中绘制函数突然不起作用
- c - 根据包含索引的另一个数组的内容对 C 字符数组进行排序
- scala - 从列表数组中获取元素的位置
- foreach - 创建一个依赖于其他 Rcpp 包的简单 Rcpp 包