正确更新 React 状态
Update React state correctly
如何正确更新反应状态?我有一个国家/地区下拉列表和一个 table 国家/地区及其城市。根据从下拉列表中选择的国家/地区,table 应仅显示该国家/地区和城市。
下面的代码第一次正确地过滤了 table 数据。更改国家/地区后,table 不会显示所选国家/地区从 秒 开始的数据。
import React, { Component } from "react";
import logo from "./logo.svg";
import "./App.css";
import { makeStyles } from "@material-ui/core/styles";
import Button from "@material-ui/core/Button";
import MenuItem from "@material-ui/core/MenuItem";
import Select from "@material-ui/core/Select";
import Table from "@material-ui/core/Table";
import TableBody from "@material-ui/core/TableBody";
import TableCell from "@material-ui/core/TableCell";
import TableHead from "@material-ui/core/TableHead";
import TableRow from "@material-ui/core/TableRow";
const useStyles = makeStyles(theme => ({
button: {
margin: theme.spacing(1)
},
input: {
display: "none"
}
}));
class App extends Component {
state = {
selectedCountry: "",
countries: []
};
constructor() {
super();
this.state.countries = [
this.createData("US", "DC"),
this.createData("UK", "London"),
this.createData("Aus", "Canberra"),
this.createData("US", "Newyork"),
this.createData("UK", "Birmingham"),
this.createData("Aus", "Sidney")
];
}
createData(country, capital) {
return { country, capital };
}
handleChange(value) {
this.setState({ selected: value });
this.setState({
countries: this.state.countries.filter(c => c.country === value)
});
}
render() {
return (
<div className="App">
<label value="Select Country: ">Select Country: </label>
<Select
style={{ width: "10%" }}
value={this.state.selected}
onChange={event => this.handleChange(event.target.value)}
name="country"
displayEmpty
>
<MenuItem value="" disabled>
Select a country
</MenuItem>
<MenuItem value="US">US</MenuItem>
<MenuItem value="UK">UK</MenuItem>
<MenuItem value="AUS">Aus</MenuItem>
</Select>
<Table>
<TableHead>
<TableRow>
<TableCell align="center">Country</TableCell>
<TableCell align="center">Capital city</TableCell>
</TableRow>
</TableHead>
<TableBody>
{this.state.countries.map(row => (
<TableRow key={row.name}>
<TableCell align="center">{row.country}</TableCell>
<TableCell align="center">{row.capital}</TableCell>
</TableRow>
))}
</TableBody>
</Table>
</div>
);
}
}
export default App;
问题就在这里,
this.setState({
countries: this.state.countries.filter(c => c.country === value)
});
此处您过滤 countries
数组并将其存储到相同的数组中。因此,当您第一次过滤时,原始 countries
数组会发生变化,您只有过滤后的数据。在下一个过滤器中,您将过滤来自先前结果而不是原始数组的数据。
您需要在构造函数中保留原始数据的副本,
constructor() {
super();
//This is initial state
this.state.countries = [
this.createData("US", "DC"),
this.createData("UK", "London"),
this.createData("Aus", "Canberra"),
this.createData("US", "Newyork"),
this.createData("UK", "Birmingham"),
this.createData("Aus", "Sidney")
];
//this is the copy of original data
this.countries = [
this.createData("US", "DC"),
this.createData("UK", "London"),
this.createData("Aus", "Canberra"),
this.createData("US", "Newyork"),
this.createData("UK", "Birmingham"),
this.createData("Aus", "Sidney")
];
}
现在每次都可以过滤原始数据,
this.setState({
countries: this.countries.filter(c => c.country === value)
});
注意:在你的filter
中进行比较时,你应该使用.toLowerCase()
。因为您所在州的国家/地区为 Aus
,select 中的值为 AUS
。比较小写值更好,
this.setState({
countries: this.countries.filter(c => c.country.toLowerCase() === value.toLowerCase())
});
在 render 方法中使用 const 值。当所选国家/地区发生变化时,const 值将每次更新。
删除行 this.setState({
countries: this.state.countries.filter(c => c.country === value)
});
并添加以下代码
render() {
const filteredCountries = this.state.countries.filter(c=> c.countries === this.state.selected);
return (
<div className="App">
<label value="Select Country: ">Select Country: </label>
<Select
style={{ width: "10%" }}
value={this.state.selected}
onChange={event => this.handleChange(event.target.value)}
name="country"
displayEmpty
>
<MenuItem value="" disabled>
Select a country
</MenuItem>
<MenuItem value="US">US</MenuItem>
<MenuItem value="UK">UK</MenuItem>
<MenuItem value="AUS">Aus</MenuItem>
</Select>
<Table>
<TableHead>
<TableRow>
<TableCell align="center">Country</TableCell>
<TableCell align="center">Capital city</TableCell>
</TableRow>
</TableHead>
<TableBody>
{this.state.filteredCountries.map(row => (
<TableRow key={row.name}>
<TableCell align="center">{row.country}</TableCell>
<TableCell align="center">{row.capital}</TableCell>
</TableRow>
))}
</TableBody>
</Table>
</div>
);
}
与使用另一个状态 "filteredCountries" 相比,这是解决此问题的更有效方法。
如何正确更新反应状态?我有一个国家/地区下拉列表和一个 table 国家/地区及其城市。根据从下拉列表中选择的国家/地区,table 应仅显示该国家/地区和城市。
下面的代码第一次正确地过滤了 table 数据。更改国家/地区后,table 不会显示所选国家/地区从 秒 开始的数据。
import React, { Component } from "react";
import logo from "./logo.svg";
import "./App.css";
import { makeStyles } from "@material-ui/core/styles";
import Button from "@material-ui/core/Button";
import MenuItem from "@material-ui/core/MenuItem";
import Select from "@material-ui/core/Select";
import Table from "@material-ui/core/Table";
import TableBody from "@material-ui/core/TableBody";
import TableCell from "@material-ui/core/TableCell";
import TableHead from "@material-ui/core/TableHead";
import TableRow from "@material-ui/core/TableRow";
const useStyles = makeStyles(theme => ({
button: {
margin: theme.spacing(1)
},
input: {
display: "none"
}
}));
class App extends Component {
state = {
selectedCountry: "",
countries: []
};
constructor() {
super();
this.state.countries = [
this.createData("US", "DC"),
this.createData("UK", "London"),
this.createData("Aus", "Canberra"),
this.createData("US", "Newyork"),
this.createData("UK", "Birmingham"),
this.createData("Aus", "Sidney")
];
}
createData(country, capital) {
return { country, capital };
}
handleChange(value) {
this.setState({ selected: value });
this.setState({
countries: this.state.countries.filter(c => c.country === value)
});
}
render() {
return (
<div className="App">
<label value="Select Country: ">Select Country: </label>
<Select
style={{ width: "10%" }}
value={this.state.selected}
onChange={event => this.handleChange(event.target.value)}
name="country"
displayEmpty
>
<MenuItem value="" disabled>
Select a country
</MenuItem>
<MenuItem value="US">US</MenuItem>
<MenuItem value="UK">UK</MenuItem>
<MenuItem value="AUS">Aus</MenuItem>
</Select>
<Table>
<TableHead>
<TableRow>
<TableCell align="center">Country</TableCell>
<TableCell align="center">Capital city</TableCell>
</TableRow>
</TableHead>
<TableBody>
{this.state.countries.map(row => (
<TableRow key={row.name}>
<TableCell align="center">{row.country}</TableCell>
<TableCell align="center">{row.capital}</TableCell>
</TableRow>
))}
</TableBody>
</Table>
</div>
);
}
}
export default App;
问题就在这里,
this.setState({
countries: this.state.countries.filter(c => c.country === value)
});
此处您过滤 countries
数组并将其存储到相同的数组中。因此,当您第一次过滤时,原始 countries
数组会发生变化,您只有过滤后的数据。在下一个过滤器中,您将过滤来自先前结果而不是原始数组的数据。
您需要在构造函数中保留原始数据的副本,
constructor() {
super();
//This is initial state
this.state.countries = [
this.createData("US", "DC"),
this.createData("UK", "London"),
this.createData("Aus", "Canberra"),
this.createData("US", "Newyork"),
this.createData("UK", "Birmingham"),
this.createData("Aus", "Sidney")
];
//this is the copy of original data
this.countries = [
this.createData("US", "DC"),
this.createData("UK", "London"),
this.createData("Aus", "Canberra"),
this.createData("US", "Newyork"),
this.createData("UK", "Birmingham"),
this.createData("Aus", "Sidney")
];
}
现在每次都可以过滤原始数据,
this.setState({
countries: this.countries.filter(c => c.country === value)
});
注意:在你的filter
中进行比较时,你应该使用.toLowerCase()
。因为您所在州的国家/地区为 Aus
,select 中的值为 AUS
。比较小写值更好,
this.setState({
countries: this.countries.filter(c => c.country.toLowerCase() === value.toLowerCase())
});
在 render 方法中使用 const 值。当所选国家/地区发生变化时,const 值将每次更新。
删除行 this.setState({
countries: this.state.countries.filter(c => c.country === value)
});
并添加以下代码
render() {
const filteredCountries = this.state.countries.filter(c=> c.countries === this.state.selected);
return (
<div className="App">
<label value="Select Country: ">Select Country: </label>
<Select
style={{ width: "10%" }}
value={this.state.selected}
onChange={event => this.handleChange(event.target.value)}
name="country"
displayEmpty
>
<MenuItem value="" disabled>
Select a country
</MenuItem>
<MenuItem value="US">US</MenuItem>
<MenuItem value="UK">UK</MenuItem>
<MenuItem value="AUS">Aus</MenuItem>
</Select>
<Table>
<TableHead>
<TableRow>
<TableCell align="center">Country</TableCell>
<TableCell align="center">Capital city</TableCell>
</TableRow>
</TableHead>
<TableBody>
{this.state.filteredCountries.map(row => (
<TableRow key={row.name}>
<TableCell align="center">{row.country}</TableCell>
<TableCell align="center">{row.capital}</TableCell>
</TableRow>
))}
</TableBody>
</Table>
</div>
);
}
与使用另一个状态 "filteredCountries" 相比,这是解决此问题的更有效方法。