【问题标题】:React setState only returning last item in a list saved to variableReact setState 仅返回保存到变量的列表中的最后一项
【发布时间】:2017-04-18 21:18:32
【问题描述】:

我对 React 非常陌生,目前正在做一个使用 GitHub API 通过 AJAX 返回搜索结果并能够在屏幕上列出该结果的小项目。目前我正在使用 for 循环来迭代响应数据并将该数据保存到变量中,很可能有更好的方法来做到这一点,但就像我说我是新人一样。然后我将状态设置为返回的数据。问题出在 setState 中,它只返回保存到变量的最后一个结果,而不是整个变量。下面列出的是整个组件,任何提示或建议将不胜感激。谢谢!

import axios from 'axios';
import * as React from 'react';


class User extends React.Component<any, any> {


    constructor(props: any) {
        super(props);
        this.state = {
            name: name,
            id: '',
            userInput: '',
            obj: null
        };
    }

    handleSubmit(e: any) {
        axios.get('https://api.github.com/users/' + this.state.userInput + '/repos')
            .then((response) => {
                if (response.data.length > 0) {
                    console.log('success');
                    let data1 = JSON.stringify(response.data);
                    let result = JSON.parse(data1);
                    for (let key in result) {
                        let obj = result[key];
                        let test = obj.name;
                        console.log(test);
                        this.setState({
                             name: name,
                             id: result[0].id,
                             obj: test,
                             userInput: this.state.userInput
                        })
                    };

                } else {
                    console.log('else is working');
                }
            })
            .catch((error) => {
                console.log('error ');
            });
    }

    render() {
        return (
            <div>
                <form>
                    <input type="text" onChange={this.handleUserInput.bind(this)} value={this.state.userInput} />
                    <h1>{this.state.userInput}</h1>
                    <button type="button" onClick={this.handleSubmit.bind(this)}>Submit</button>
                </form>
                <h1>Name : {this.state.name}</h1>
                <h1> ID : {this.state.id}</h1>
                <h1>OBJ : {this.state.obj}</h1>
            </div>
        );
    }
}

export default User;

安慰变量测试的结果给出了这个控制台输出 console output

但是,当 this.state.obj 在 obj 中设置它时,它只显示最后一项,如此处所示written to page

【问题讨论】:

  • 您希望 API 的所有结果都显示在 UI 上?

标签: javascript reactjs typescript


【解决方案1】:

每次调用setState,都会覆盖之前的状态。 React 尝试智能地合并提供的(新的)状态和先前的状态,但如果有任何键冲突,则(该键的)先前的状态将丢失。如果您想要您所在州的列表项目,您必须执行类似的操作

let items = [];
for (...) {
    items.push({
        name: name,
        id: result[0].id,
        ...
    });
}

this.setState({ items: items }); 

接下来,您可以使用this.state.items[someIndex]等访问列表中的每个项目

【讨论】:

    【解决方案2】:

    添加到@Tyler Sebastian 答案,您可以这样做

    let items = [];
    for (let key in result) {
        let obj = result[key];
        let test = obj.name;
        console.log(test);
        items.push({
            name: name,
            id: result[0].id,
            obj: test,
            userInput: this.state.userInput
        });
    }
    
    this.setState({ items: items }); 
    

    还有,渲染部分,我认为你可以这样做:

    return (
            <div>
                <form>
                    <input type="text" onChange={this.handleUserInput.bind(this)} value={this.state.userInput} />
                    <h1>{this.state.userInput}</h1>
                    <button type="button" onClick={this.handleSubmit.bind(this)}>Submit</button>
                </form>
                {this.state.items.map((item) => {
                  <h1>Name : {item.name}</h1>
                  <h1> ID : {item.id}</h1>
                  <h1>OBJ : {item.obj}</h1>
                })}
    
            </div>
        );
    

    【讨论】:

      【解决方案3】:

      感谢您的回答和提示,我非常感谢。最终发生的事情是,因为我在 for 循环中调用 setState,它实际上显示了所有项目,但它是在一瞬间并且​​会在最后停止,所以它看起来好像只是显示最后一个。这就是我最终修复它的方式。

      handleSubmit(e: any) {
          axios.get('https://api.github.com/users/' + this.state.userInput + '/repos')
              .then((response) => {
                  if (response.data.length > 0) {
                      console.log('success');
                      let data1 = JSON.stringify(response.data);
                      let result = JSON.parse(data1);
                      let list = '';
                      for(let i of result) {
                          list += i.name + ' ';
                      }
                      console.log(list);
                      this.setState({
                          name: result[0].name,
                          id: result[0].id,
                          obj: list,
                          userInput: this.state.userInput
                      })
      
                  } else {
                      console.log('else is working');
                  }
              })
              .catch((error) => {
                  console.log('error ');
              });
      }
      

      绝对不是最好的方法,但至少它正在工作,我可以努力改进它。非常感谢大家的帮助!

      【讨论】:

        猜你喜欢
        • 2016-12-31
        • 1970-01-01
        • 1970-01-01
        • 2021-07-30
        • 2016-10-24
        • 2018-08-17
        • 1970-01-01
        • 2022-01-08
        • 2011-01-30
        相关资源
        最近更新 更多