javascript - React 输入字段将空字符串记录为第一次击键

标签 javascript reactjs

我不确定我做错了什么,但我有一个输入字段,用于输入搜索词并尝试根据搜索词过滤结果。问题是传递的第一个值是一个空字符串,此后每次按键输入都会偏移 1 个项目。例如,如果我输入“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;

最佳答案

setState 是异步的,因此当您调用 updateResults 时,您的 this.state.searchTerm 不会更新。你可以例如相反,在渲染中过滤数组。

示例

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>
    );
  }
}

关于javascript - React 输入字段将空字符串记录为第一次击键,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51087715/

相关文章:

reactjs - 如何在React Native中导入组件过去的两个文件夹?

javascript - 带 iframe 的跨域 localStorage (Chrome)

javascript - 如何通过 ul 中的索引将类设置为 li 标签

javascript - 在用户键入时修改 HTML 文本区域?

javascript - Reactjs : Invariant Violation when using input element

javascript - redux 中的状态更新

reactjs - 使用 Typescript 3.5+ 在 React 中覆盖子属性

javascript - 根据 JavaScript 中的数组更改 div 背景颜色?

javascript - 将回调中的变量返回到定义的函数中-NodeJS

reactjs - typescript 错误: Cannot find module 'moment'