【问题标题】:Why is React treating my array as if it were empty?为什么 React 将我的数组视为空的?
【发布时间】:2019-01-10 15:42:52
【问题描述】:

我目前正在使用 MERN 堆栈创建一个全堆栈应用程序,但遇到了一个以前没有遇到的问题。当我使用 .map() 函数迭代我的数组时,即使控制台记录了我的数组存在,长度为 4,并且具有所有正确的元素(它们是对象),我的数组没有被.map() 函数迭代。

我还注意到,当我在控制台登录 array.length 时,我的值为零 - 尽管在之前的日志中我被告知该数组的长度为 4(它应该如此)。

下面是我填充数组的地方:

getTournaments(){
        fetch("http://localhost:3001/tournament", {
            credentials: 'include',
            method: "get",
            headers: {
                'Accept':'application/json',
                'Content-Type': 'application/json',
            }
        })
        .then( (response) => response.json())
        .then( (response) => {
            if(response){
                response.map((tournament)=> {
                    this.state.tournaments.push(tournament);
                })
            }
        })
    }

我在这里打电话给getTournaments()

componentDidMount(){

        this.getTournaments(); ...

这就是我尝试映射数组的方式:

this.state.tournaments.map((tournament,index) => {
   return (<div key={index}> {tournament.title} </div>);
})

最后,我的控制台日志是在我调用渲染函数时创建的。 这是渲染函数:

renderSpectatorView(){
        var array = [1,2,3];
        var currentTournaments = this.state.tournaments;
        // console.log(currentTournaments);
        return(
            <div className="page-wrapper">

                            {/* BOOTSTRAP MODAL */}
            {this.state.isAuth ? <Button onClick={this.goToCreate} bsStyle="primary">Create Tournament</Button> : null}
            <div className="tournament-wrapper">
                     {  
                        console.log(this.state.tournaments)}
                       { console.log(this.state.tournaments.length)}

            </div>
            </div>
        );
    }

我在项目早期使用了几乎相同的方法(但更复杂,因为我迭代了数组中每个对象的属性),所以我很难理解为什么这不起作用。我最初的想法是,在我完成从我的 API 获取数据之前,可能正在调用渲染函数 - 但值记录正确。

我应该使用 Promise 还是 async/await 来实现这一点,以确保仅在收集数据后才进行渲染?感谢您的任何帮助。

【问题讨论】:

  • 您在第一次 sn-p 中尝试映射时,response 的值是多少?
  • 问题是this.state.tournaments.push(tournament);。您必须使用 setState 来触发重新渲染

标签: javascript arrays reactjs ecmascript-6


【解决方案1】:

问题是this.state.tournaments.push(tournament);

如果您想触发更新,您必须使用 setState。 做类似的事情

.then( (response) => {
    if(response){
        this.setState({tournaments: [...this.state.tournaments, ...response.tournaments]});
    }
})

传播是因为看起来您已经在 this.state.tournaments 中拥有想要保留的值,我不完全确定。 如果你只设置一次,你可以简单地做

.then( (response) => {
    if(response){
        this.setState({tournaments: response.tournaments});
    }
})

查看这里了解更多信息ReactJS Docs: Do Not Modify State Directly

简而言之;你可以永远在没有setState 的情况下改变状态,你不能做this.state.thing = X,你不能做this.state.thing.push(),或其他任何事情。修改state 的唯一方法是使用setState

【讨论】:

  • this.state.tournaments 只是一个空数组。我想用当前存储在数据库中的任何锦标赛替换那个空数组,并在每次刷新/访问页面时检查数据库的更改(oncomponentdidmount)。我将状态修改切换为使用setState,一切正常!感谢您的回答。在工作了几个星期后,我开始远离 setState ......猜猜我的懒惰赶上了我。
  • 我会回去寻找您可能没有使用过的其他地方。如果没有 setState,事情可能会巧合,因为许多其他事情可能会触发组件重新渲染。如果您遇到此类情况,您可能最终会发现晦涩难懂的错误。由于您只是设置它一次,因此您可以忽略我答案的第一部分,而只需使用更简单的第二个示例。很高兴为您提供帮助
  • 同意——这正是我的想法。为自己省去一些未来的麻烦。
猜你喜欢
  • 2013-10-14
  • 1970-01-01
  • 2014-06-24
  • 2020-11-15
  • 2012-09-22
  • 2014-01-22
相关资源
最近更新 更多