我不确定自己在做什么错,但是我有一个输入字段,用于输入搜索词并尝试根据搜索词过滤结果。问题是传递的第一个值是一个空字符串,此后每次按键输入都会偏移一个项目。例如,如果我键入“ sea”,它将把搜索词更新为“ se”。然后,当我尝试删除该值时,它会向另一个方向偏移,因此删除“ se”以“ s”结尾,无法删除。
(以下是正在进行的应用程序的链接:https://vibrant-yonath-715bf2.netlify.com/allpokemon。完整的搜索功能尚无法使用。对此我很陌生。)
import React, { Component } from 'react';
import Pokemon from './Pokemon';
class PokemonList extends Component {
constructor(props) {
super(props);
this.state = {
pokemonList: [],
searchTerm: '',
fetched: false,
loading: false
};
this.updateResults = this.updateResults.bind(this);
}
componentWillMount() {
this.setState({
loading: true
});
fetch('https://pokeapi.co/api/v2/pokemon?limit=151')
.then(res => res.json())
.then(response => {
this.setState({
pokemonList: response.results,
loading: true,
fetched: true
});
});
}
handleSearchTermChange = (
event: SyntheticKeyboardEvent & { target: HTMLInputElement }
) => {
this.setState({ searchTerm: event.target.value });
this.updateResults();
};
updateResults() {
const filteredList = this.state.pokemonList.filter(
pokemon =>
pokemon.name.toUpperCase().indexOf(this.state.searchTerm.toUpperCase()) >= 0
);
console.log(this.state.searchTerm);
this.setState({
pokemonList: filteredList
});
}
render() {
const { fetched, loading, pokemonList } = this.state;
let content;
if (fetched) {
content = (
<div className="flex-grid">
{pokemonList.map((pokemon, index) => (
<Pokemon key={pokemon.name} id={index + 1} pokemon={pokemon} />
))}
</div>
);
} else if (loading && !fetched) {
content = <p> Loading ...</p>;
} else {
content = <div />;
}
return (
<div>
<input
onChange={this.handleSearchTermChange}
value={this.state.searchTerm}
type="text"
placeholder="Search"
/>
{content}
</div>
);
}
}
export default PokemonList;
答案 0 :(得分:1)
setState
是异步的,因此调用this.state.searchTerm
时不会更新updateResults
。您可以例如而是在渲染中过滤数组。
示例
class App extends Component {
state = {
pokemonList: [
{ name: "pikachu" },
{ name: "bulbasaur" },
{ name: "squirtle" }
],
searchTerm: ""
};
changeSearchTerm = event => {
this.setState({ searchTerm: event.target.value });
};
render() {
const { pokemonList, searchTerm } = this.state;
const filteredList = pokemonList.filter(pokemon =>
pokemon.name.toUpperCase().includes(searchTerm.toUpperCase())
);
return (
<div>
<input value={searchTerm} onChange={this.changeSearchTerm} />
{filteredList.map(pokemon => <div>{pokemon.name}</div>)}
</div>
);
}
}
答案 1 :(得分:0)
我认为问题在于您致电this.updateResults();
然后调用this.setState({ searchTerm: event.target.value });
而不是对setState
使用回调函数。
例如:
this.setState({ searchTerm: event.target.value }, () => this.updateResults());
希望我做对了。
更新:
我还在您的代码中看到了许多问题,例如,为什么用过滤列表更新列表?您不需要这样做:
this.setState({
pokemonList: filteredList
});
您无需仅更新状态中的结果,而只需要呈现已过滤的列表... ...意味着您的状态将保留在原始列表中,也将包含已过滤的value
,仅在呈现时您传递已过滤的列表..