更新代码初始化构造函数,并在类呈现方法中放置过滤器和loadOptions。仍然显示错误提示this.state.cars.filter不是一个函数
import React, { Component } from 'react';
import AsyncSelect from 'react-select/async';
export default class Search extends Component {
constructor(props) {
super(props);
this.state = {
inputValue: null,
cars: []
};
}
componentDidMount() {
fetch(url)
.then(res => {
this.setState(prevState => ({...prevState, cars: res}))
})
}
handleInputChange = (newValue) => {
const inputValue = newValue.replace(/W/g, '');
this.setState({ inputValue });
return inputValue;
};
render() {
const filterCars = (inputValue) => {
return this.state.cars.filter((i) =>
i.label.toLowerCase().includes(inputValue.toLowerCase())
);
};
const loadOptions = (
inputValue,
callback) => {
setTimeout(() => {
callback(filterCars(inputValue));
}, 1000);
};
return (
<div>
<AsyncSelect
cacheOptions
loadOptions={loadOptions}
defaultOptions
onInputChange={this.handleInputChange}
/>
</div>
);
}
}
从
获取数据的json文件示例代码[{"make":"KIA","link":"/images/image.jpg"},{"make":"BMW","link":"/images/image.jpg"}]
这里有几个问题。首先,你应该在构造函数内部声明状态,因此,与其这样声明状态,不如这样做:
constructor(props) {
super(props)
this.state = {inputValue: '', cars: []}
}
那么你需要处理你的state mutations
。当你调用setState
时,你实际上给了它一个新的object
它将state
设置为。您不重新分配properties
,您返回一个新的object
。
为了解决这个重赋问题,ES6
引入了spread operator
,它不是专门为处理突变而设计的,但它很有帮助。
基本上,当你想要创建一个对象的副本时,你不需要
let a = b
而不是
let a = {...b}
有了这个变化,A的变化不会反映在b上,所以你做了一个副本而不是副本。
如何使用它来避免状态突变?
无论何时调用setState
,在进行任何属性更改之前,请确保首先将状态的其余部分扩展到新状态:
setState(prevState => ({...prevState, cars: res}))
这样,您就不必从状态对象中删除inputValue
,否则会导致未定义的问题。
回到主要问题,你的函数filterCars
位于你的类之外,在那里你试图访问this.state
。将filterCars
函数移动到类内部,您的错误将得到解决,但如果您不解决突变问题,它将无法按预期工作。