[英]React Filter the state without mutating the array
我知道我犯了一個愚蠢的錯誤,但我似乎無法弄清楚它是什么。 我的狀態中有一個列表,根據用戶從下拉列表中選擇的內容,狀態會更新。 但是我以某種方式改變了狀態,所以當用戶第二次選擇某些東西時,列表是空的,屏幕上沒有任何顯示。
import React, { Component } from 'react';
import axios from 'axios';
import Sidebar from './components/Sidebar'
import Map from './components/Map'
require('dotenv').config();
class App extends Component {
state = {
incidents: [],
map: false,
options: []
}
async componentDidMount() {
const res = await axios.get('https://data.sfgov.org/resource/wr8u-xric.json', {
params: {
"$limit": 500,
"$$app_token": process.env.APP_TOKEN
}
})
const incidents = res.data;
this.setState({ incidents });
console.log(incidents)
this.getOptions()
};
getMap = () => {
this.setState({ map: true });
console.log(this.state.options)
}
handleChange = (e) => {
const items = this.state.incidents.filter(incident => incident['zip_code'] === e.target.value)
this.setState({incidents: items})
}
getOptions = () => {
this.state.incidents.map(incident => {
if(!this.state.options.includes(incident['zip_code'])){
this.state.options.push(incident['zip_code'])
}
})
}
render() {
return (
<div>
<h1> San Francisco Fire Incidents</h1>
<button onClick={this.getMap}> Get Map</button>
<div id="main">
<div style={{ width: '20%', height: '900px', display: 'inline-block', overflow: 'scroll', marginRight: '2px' }}>
<span> Zip Code</span>
<form>
<select value={this.state.value} onChange={this.handleChange}>
{this.state.options.map(option => (
<option value={option} key={option}>{option}</option>
))}
</select>
</form>
</div>
{
this.state.map ? <Map incidents={this.state.incidents} /> : ''
}
</div>
</div>
);
}
}
export default App;
問題是你沒有在任何地方保持初始狀態。
因此,在改變狀態並刪除項目之后,預計狀態變量將不包含所有原始項目。
更改為如下所示:
import React, { Component } from 'react';
import axios from 'axios';
import Sidebar from './components/Sidebar'
import Map from './components/Map'
require('dotenv').config();
class App extends Component {
state = {
initialIncidents: [],
incidents: [],
map: false,
options: []
}
async componentDidMount() {
const res = await axios.get('https://data.sfgov.org/resource/wr8u-xric.json', {
params: {
"$limit": 500,
"$$app_token": process.env.APP_TOKEN
}
})
const incidents = res.data;
this.setState({ initialIncidents: incidents });
console.log(incidents)
this.getOptions()
};
getMap = () => {
this.setState({ map: true });
console.log(this.state.options)
}
handleChange = (e) => {
const items = this.state.initialIncidents.filter(incident => incident['zip_code'] === e.target.value)
this.setState({incidents: items})
}
getOptions = () => {
this.state.incidents.map(incident => {
if(!this.state.options.includes(incident['zip_code'])){
this.state.options.push(incident['zip_code'])
}
})
}
render() {
return (
<div>
<h1> San Francisco Fire Incidents</h1>
<button onClick={this.getMap}> Get Map</button>
<div id="main">
<div style={{ width: '20%', height: '900px', display: 'inline-block', overflow: 'scroll', marginRight: '2px' }}>
<span> Zip Code</span>
<form>
<select value={this.state.value} onChange={this.handleChange}>
{this.state.options.map(option => (
<option value={option} key={option}>{option}</option>
))}
</select>
</form>
</div>
{
this.state.map ? <Map incidents={this.state.incidents} /> : ''
}
</div>
</div>
);
}
}
export default App;
我認為這部分有問題
getOptions = () => {
this.state.incidents.map(incident => {
if(!this.state.options.includes(incident['zip_code'])){
this.state.options.push(incident['zip_code'])
}
})
}
當您搜索時,您總是在改變狀態選項。 如果未找到結果,則選項數組將為空。
嘗試做這樣的事情。
getOptions = () => {
let options = [...this.state.options]
this.state.incidents.map(incident => {
if(!this.state.options.includes(incident['zip_code'])){
options.push(incident['zip_code'])
}
})
this.setState({options});
}
this.state.incidents
包含所有事件,當用戶進行第一個選擇時,您正在更改incidents
數組。 第二個選擇是從第一個選擇中過濾已經過濾的事件並返回 empty 。 這可能會導致此問題。
const items = this.state.originalIncidents.filter(incident => incident['zip_code'] === e.target.value)
this.setState({incidents: items})
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.