Javascript 使用API调用响应setState延迟更新

Javascript 使用API调用响应setState延迟更新,javascript,json,reactjs,axios,setstate,Javascript,Json,Reactjs,Axios,Setstate,我是个新手,在创建项目的过程中,我在代码中遇到了一个相当奇怪的事件。 它具有setState的异步特性,不允许我在页面上呈现我希望的数据。 我正在尝试将数据库中已有的文件显示到我的网页上。但是由于状态是在一段时间后设置的,因此我无法使用map函数将文件渲染到屏幕上,因为调用它时,它是未定义的 我在中实现了一个get方法,以便获取要显示的文件的json响应。但当我挂载我的组件并设置文件的状态时,它显示它没有任何值。我知道它是异步的,但我不知道如何处理它,以便我可以使用map显示在网页上 我的代码如

我是个新手,在创建项目的过程中,我在代码中遇到了一个相当奇怪的事件。 它具有setState的异步特性,不允许我在页面上呈现我希望的数据。 我正在尝试将数据库中已有的文件显示到我的网页上。但是由于状态是在一段时间后设置的,因此我无法使用map函数将文件渲染到屏幕上,因为调用它时,它是未定义的

我在中实现了一个get方法,以便获取要显示的文件的json响应。但当我挂载我的组件并设置文件的状态时,它显示它没有任何值。我知道它是异步的,但我不知道如何处理它,以便我可以使用map显示在网页上

我的代码如下:

import React, {Component} from "react";
// import axios from 'axios'; 
import {Link} from 'react-router-dom';
import {Styles} from '../Styling/Styles';
  

class FileView extends Component {

    state = {
        fileViewData : {}
    }

    // viewFunction(){
    componentDidMount(){

          fetch('http://127.0.0.1:8000/api/uploads/', {
                method: 'GET'
            })
            .then((response) => {
                let data = response.json();
                return data;
            })
            .then((data) => {
                this.setState({fileViewData: data}, ()=>{
                    console.log("hi");
                });
            }).catch(error => {console.log(error)})
            

            // console.log(fileViewData);
            
    }

    render(){
   
        return (

            <React.Fragment>
                <Styles>
                <div className = "appbar">
            
                <Link to='/dashboard'>
                    <button className="homeBtn" label="Back" >
                    Back
                    </button>
                </Link>

                </div>

                {/* <button  label="View" onClick={this.viewFunction} >
                    View
                </button> */}
        
            </Styles>

            //.....section not working since map is not a function of undef......//
            {   

               this.state.fileViewData.map(item =>{
                    return (
                        <h2>{item.fields.file}</h2>
                            );
                            
                 })

            }

            //.......section not working ends.........//
            
            {console.log(this.state.fileViewData)}

        </React.Fragment>
        );
    }
    
}

export default FileView;

控制台输出如下所示:

空对象返回两次,然后数据返回两次。我也没有运行任何类型的循环。
我应该如何设置该值,以便能够在屏幕上显示我的文件?蒂亚

看起来您的数据是一个数组,所以您的初始状态也应该是一个数组

state = {
  fileViewData: [],
}
那么,您对数组长度的检查将是正确的,但是常规javascript在JSX中的工作方式并不完全相同。您需要有条件地呈现JSX

由于如果没有数据,您似乎不会真正渲染任何内容,因此可以简单地将数据映射为array::map正确处理空数组

{
  this.state.fileViewData.map(...)
}

看起来您的数据是一个数组,所以您的初始状态也应该是一个数组

state = {
  fileViewData: [],
}
那么,您对数组长度的检查将是正确的,但是常规javascript在JSX中的工作方式并不完全相同。您需要有条件地呈现JSX

由于如果没有数据,您似乎不会真正渲染任何内容,因此可以简单地将数据映射为array::map正确处理空数组

{
  this.state.fileViewData.map(...)
}
将状态设置为空数组 从map语句中删除if条件和匿名函数声明 您声明了该函数,但从未调用它,而且您也不需要它

如果你坚持检查长度

{   
    this.state.fileViewData.length &&
        this.state.fileViewData.map(item =>{
            return (
                <h2>{item.fields.file}</h2>
            );
        })
}
将状态设置为空数组 从map语句中删除if条件和匿名函数声明 您声明了该函数,但从未调用它,而且您也不需要它

如果你坚持检查长度

{   
    this.state.fileViewData.length &&
        this.state.fileViewData.map(item =>{
            return (
                <h2>{item.fields.file}</h2>
            );
        })
}

您将获得多个控制台日志,因为当您在React中设置状态时,会导致组件再次渲染

至于您的实现,您可能希望fileViewData的初始值与后端返回的数据结构相同。目前,您从一个普通javascript对象开始,然后在后端收到响应后将其转换为一个对象数组


在不考虑加载时间的情况下,要使应用程序在数据加载之前不会崩溃,一个简单的方法是在初始化fileViewData时使其成为空数组,而不是没有键的对象。然后,它将拥有正确的原型来拥有方法映射。

您将获得多个控制台日志,因为当您在React中设置状态时,会导致组件再次渲染

至于您的实现,您可能希望fileViewData的初始值与后端返回的数据结构相同。目前,您从一个普通javascript对象开始,然后在后端收到响应后将其转换为一个对象数组


在不考虑加载时间的情况下,要使应用程序在数据加载之前不会崩溃,一个简单的方法是在初始化fileViewData时使其成为空数组,而不是没有键的对象。然后它会有正确的原型来拥有方法映射。

oh,并将fileViewData初始设置为[],然后您可以直接使用map。oh,将fileViewData初始设置为[],然后您可以直接使用map。谢谢!这管用!非常感谢。这管用!