繁体   English   中英

ReactJs setState跳过第一个字母

[英]ReactJs setState skips first letter

每当我输入的内容是搜索栏的更新状态时,都会跳过第一个字母。 例如,如果我写“ asdf”,则仅显示“ sdf”。

我在这行代码之前尝试过console.log

this.props.newQuery(this.state.newSearchQuery);

而且一切正常。

请检查下面的App.js和SearchBar.js代码

谢谢

App.js

import React from 'react';

import SearchBar from './components/SearchBar';

class App extends React.Component {
  constructor(){
    super();

    this.state = {
      searchQuery: '',
      fetchedData: []
    };
  }

  newQuery(query){
    this.setState({
      searchQuery: query
    });
  }

  onSearch(){
    const userInput = this.state.searchQuery;

    if(userInput !== '' && userInput !== ' '){
      const API_KEY = `https://pokeapi.co/api/v2/pokemon/${userInput}`;

      fetch(API_KEY, {
        method: 'GET',
        headers: {
          Accept: 'application/json'
        }
      })
      .then(result => result.json())
      .then(data => this.setState({ fetchedData: data.results }));

      console.log('res', this.state.fetchedData);
    }
  }

  render(){
    return(
      <div className="App">
        <h2>Search Pokemos by Types</h2>
        <hr />
        <SearchBar onSearch={this.onSearch.bind(this)} newQuery={this.newQuery.bind(this)} />
      </div>
    );
  }
}

export default App;

SearchBar.js

import React from 'react';

class SearchBar extends React.Component {
    constructor(props){
        super(props);

        this.state = {
            newSearchQuery: '' //this blank value get executed first when i console.log
        }
    }
    searchInput(event){
        this.setState({
            newSearchQuery: event.target.value
        });

        this.props.newQuery(this.state.newSearchQuery);

        console.log(this.state.newSearchQuery); // if i log "asdf", state on top "newSearchQuery" skips the first letter, a and shows "sdf" only.
    }

    render(){
        return(
            <div className="input-group">
                <input onChange={this.searchInput.bind(this)} className="form-control" placeholder="[eg. Ditto, Cheri, etc]" />

                <button onClick={this.props.onSearch} className="btn btn-success">Search</button>
            </div>
        );
    }
}

export default SearchBar;

console.log不会按预期方式记录日志,因为setState()方法并不总是按其调用方式执行。 根据Docs

状态更新可能是异步的 :由于this.propsthis.state可能是异步更新的,因此不应依赖于它们的值来计算下一个状态。

因此,当您记录此console.log(this.state.newSearchQuery); setState ,状态实际上并未更改,因此这就是为什么它记录意外的原因

关于这两个组件之间的冗余状态,我有些困惑。 我想我会做的(如果我没有使用mobx之类的东西)是将状态保留在父组件上,并将handleChangehandleSearch函数传递给<Search />组件。 看起来像...

我为您整理了一个codeandbox: https ://codesandbox.io/s/n1ryz4rzwl

APP组件

import React, { Component } from 'react';
import SearchBar from './components/SearchBar'

class App extends Component {
  constructor() {
    super()
    this.state = {
      searchQuery: '',
      fetchedData: []
    }
  }

  handleChangeQuery = event => this.setState({searchQuery: event.target.value})

  handleSearch = () => {
    const {searchQuery} = this.state,
      API_KEY = `https://pokeapi.co/api/v2/pokemon/${searchQuery}`;

    fetch(API_KEY, {
      method: 'GET',
      headers: {
        Accept: 'application/json'
      }
    })
    .then(result => result.json())
    .then(data => this.setState({ fetchedData: data.results }));
  }

  render() {
    const {searchQuery} = this.state
    return (
      <div className="App">
        <h2>Search Pokemos by Types</h2>
        <hr />
        <SearchBar
          value={searchQuery} 
          handleChangeQuery={this.handleChangeQuery} 
          handleSearch={this.handleSearch}  
        />

        // Show fetchedData results here

      </div>
    )
  }
}

export default App

SearchBar组件 - 组件 可以是无状态功能组件

import React from 'react'

const SearchBar = ({value, handleChangeQuery, handleSearch}) => {
  return (
    <div className="input-group">
      <input 
        onChange={handleChangeQuery} 
        value={value}
        className="form-control" 
        placeholder="[eg. Ditto, Cheri, etc]" 
      />
      <button onClick={handleSearch} className="btn btn-success">Search</button>
    </div>
  )
}

export default SearchBar

其他注释已经描述了奇怪的丢失字符背后的原因-因为this.setState()可能是异步的。 但是, this.setState()确实具有一个回调函数,如果您要进行测试,可用于确认更改。 看起来像:

this.setState({key: value}, () => {
  // State has been set
  console.log(this.state.key)
})

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM