【问题标题】:setState does not set the state properly, when dropdown values changes当下拉值更改时,setState 未正确设置状态
【发布时间】:2019-06-02 06:58:11
【问题描述】:

我遇到了这种情况,我有一个下拉菜单,可以拉出用户的帐户,然后根据其选择更改页面内容。我正在尝试一种如下所示的方法,似乎 setState 没有被正确调用,或者调用序列可能是错误的。没有真正得到什么是错的。更改下拉值不会更新内容。

我们将不胜感激。

import * as React from 'react';
import Select from 'semantic-ui-react/dist/commonjs/addons/Select';

interface IState{
  accountDetails[], // stores all details w.r.t an account
  userAccounts: [], // stores all accounts w.r.t a user
  selectedAccount : string, // selected account from the dropdown
  [x: string] : any,
}

export default class App extends React.Component<{},IState> {

  constructor(props:any){
    super(props);
    this.state = {
      accountDetails: [],
      userAccounts: [],
      selectedAccount: ''
    }
  }

  dropdownChange = (event: React.SyntheticEvent<HTMLElement>, data:any) => {
     this.setState(prevState => ({
      selectedAccount: data.value
     }), () => {});
  }

  async componentDidMount()
  {
      await this.fetchUserAccounts();
  }  


  fetchUserAccounts = async() => {
    //fetch API call for getting all user accounts by passing a user ID
    // I am able to get the data
    fetch('/api/fetch/accounts'
      .then(response => response.json())
      .then(data => this.setState({ userAccounts: data}));
    this.fetchAccountDetails();
  }    

  fetchAccountDetails = async() =>
  {
       let URL = "/api/fetch/account?accountId=" +this.state.selectedAccount;
       fetch('URL'
        .then(response => response.json())
        .then(data => this.setState({ accountDetails: data}));
  }

  render() {
    return(
       <div>
         <Select 
                 options={this.state.userAccounts} 
                 name="selectedAccount"  
                 value={this.state.selectedAccount}
                 onChange={this.dropdownChange}                         
        />
        // component to display the details
        <DetailComponent accounts={this.state.accountDetails} />
      </div>
    )
  }
}

【问题讨论】:

  • 当下拉列表发生变化时,您不会再次调用fetchAccountDetails 函数来获取帐户详细信息。

标签: reactjs typescript setstate semantic-ui-react


【解决方案1】:

您需要在更改状态后立即调用fetchAccountDetails,以便使用下拉列表已更改的最新状态调用该函数:

  dropdownChange = (event: React.SyntheticEvent<HTMLElement>, data:any) => {
     this.setState(prevState => ({
      selectedAccount: data.value
     }), () => { this.fetchAccountDetails() });
  }

【讨论】:

  • 是的,可以获取与帐户对应的帐户详细信息。但是下次如果我更改下拉值,详细信息会被复制。就像之前获取的帐户详细信息的副本会被复制
  • 您能否详细说明一下 - 您所说的“复制”是什么意思?如果您将下拉菜单更改为不同的值,会发生什么?
  • 如果我在帐户中有两个值,比如 1 和 2,其中 1 有数据,而 2 没有数据。如果我从下拉数据中选择 1,然后显示,如果我选择 2,则第一个数据不会被清除(即使我从后端没有得到 2 的结果)。下次如果我选择 1 ,则 1 的相同内容将被添加到以前的数据中。
  • 请发布您从 API 获得的结果和DetailComponent 的代码。
  • 您还应该尝试调试您刚刚指定的场景中发生的情况。使用console.log(data)
【解决方案2】:

setState 函数是异步的,这意味着在更新状态时需要特别注意,并期望在状态中同步使用更新的值。出于这个原因,setState 函数有第二个参数,它允许您指定在状态实际更新时执行的回调。这是您需要调用fetchAccountDetails 函数的地方。

您可以在 React 文档 here 中找到 setState 回调参数。

但是无论哪种方式编译都会有问题。 (a) 你的界面应该以分号结束每个成员声明,​​而不是逗号。 (b) 在调用fetch 时,您在每一行都缺少一个“)”。 (c) 在fetchAccountDetails 函数中,您声明了URL 变量,但随后您将字符串'URL' 传递给fetch 函数,而不是变量。

这是一个有效的代码沙盒,显示了您的问题的修复和语法修复。我已经注释掉了对 fetch 函数的调用,因为它们无论如何都会失败。

https://codesandbox.io/s/thirsty-rain-2u69e

【讨论】:

    猜你喜欢
    • 2020-03-08
    • 1970-01-01
    • 1970-01-01
    • 2022-06-16
    • 2018-09-23
    • 2015-03-26
    • 2018-10-19
    • 2020-01-15
    • 1970-01-01
    相关资源
    最近更新 更多