【问题标题】:React- Should I be using promises to set state?React-我应该使用承诺来设置状态吗?
【发布时间】:2017-08-01 21:10:22
【问题描述】:

我正在尝试使用 js + React,但遇到了意想不到的行为:

在以下示例中,虽然一开始似乎工作正常,但当 (this.state.progress.length%3==0) 符合预期时,我没有得到分数变化。

进度字符串似乎更新得很好,但得分每四次点击更新一次...

编辑:我应该指出问题的根源,因为 ppl 很忙,问题是子组件上的 handleClick() 交互方式(调用) 来自同一组件的scoreUpdate()。但是我不认为解决方案是微不足道的,因为问题末尾的 consol.log() 示例有效。

我组织代码的方式显然存在问题,但是什么?

我应该使用 Promises 来调用我的scoreUpdate() 函数吗?

或者有没有更好的方法来解决这个问题?

子组件:

import React from 'react';

export class Child extends React.Component {

constructor(props) {
super(props);

this.state = { progress: "0",
               score: 0};
this.handleClick = this.handleClick.bind(this);
this.scoreUpdate = this.scoreUpdate.bind(this);
}

handleClick(e) {

let previous = this.state.progress;

let score = Number(e.currentTarget.id);

this.setState({progress: previous+e.currentTarget.id});

this.scoreUpdate(score);

}  

scoreUpdate(score) {


if (this.state.progress.length%3==0) {

let previous = this.state.score;

this.setState({score: previous+score}); }

}

render() {


return (
  <div>
    <ul>
      <li id="1" onClick={this.handleClick}>a</li>
      <li id="2" onClick={this.handleClick}>b</li>
    </ul>

    <p>progress</p>
    <p>{this.state.progress}</p>
    <p>progress length</p>
    <p>{this.state.progress.length}</p>
    <p>score</p>
    <p>{this.state.score}</p>
  </div>
);
}
}

父组件:

import React from 'react';
import ReactDOM from 'react-dom';
import {Child} from './components/Child';

class Parent extends React.Component {  

render() {

return (
  <Child />
);
}
}

ReactDOM.render(
<Parent />,
document.getElementById('app')
);

任何关于为什么会出现这种情况的有效见解/解释都将受到高度赞赏。令我困惑的是,当我在控制台中输入时:

var b = 1;

function c() {
b=b+2;
d();
}

function d() {
console.log(b);
 }

c();

这会按预期返回 3。

如果您知道此问题有重复,请留下评论以便我将其删除。

【问题讨论】:

  • 你到底在哪里使用 Promise?
  • 你想要完成什么?
  • 通过 setState() 中的回调解决问题!

标签: javascript reactjs scope


【解决方案1】:

试试这样:

handleClick(e) {

    let previous = this.state.progress;

    let score = Number(e.currentTarget.id);

    this.setState({progress: previous+e.currentTarget.id}, () => this.scoreUpdate(score));

}  

scoreUpdate(score) {


    if (this.state.progress.length%3==0) {

    let previous = this.state.score;

    this.setState({score: previous+score}); }

}

【讨论】:

  • 我现在正在尝试。它看起来非常专业。想多解释一下吗?
  • 难以置信!有效!!您是否在 setState 上设置回调?优秀的。泰。尽管问题末尾的 console.log 示例有效,但请解释为什么之前的公式无效?
  • @alexandros84,这里是docs
  • this answer 应该会有所帮助:)
【解决方案2】:

我为您的组件提供了setup a JSFiddle,但我仍然完全不知道发生了什么。您的state.progress 似乎是event.targetid 属性的字符串连接:例如0111

因此,每次调用scoreUpdate 时,它都会在末尾添加id(在JSFiddle 的情况下为always 1)属性:

  • 点击1:state.progress === 0
  • 点击2:state.progress === 01
  • 点击3:state.progress === 011
  • 点击4:state.progress === 0111

只有在第四次点击时this.state.progress.length % 3 == 0 才会产生true,因此会更新state.score

请解释一下?

【讨论】:

  • 等待它不应该总是 1 id,因为我已经手动设置了两个
  • 元素,id 为 1 和 2...
  • 请更新我创建的 JSFiddle。没关系,但是由于您没有指定 render,我只是设置了 buttonid=1
  • 努力工作,但小提琴仅由一个组件组成。这就是为什么你很难理解正在发生的事情。这个想法是有两个元素“a”和“b”的列表,id 分别为 1 和 2。当您单击其中一个时,进度字符串会在其状态中添加此 ID,并且每 3 次单击您应该在您的分数中添加此数字 ID。然而,尽管我尽了最大的努力,但当 progress.length 为 3 时,分数并未更新,而是在 progress.length 为 4 时更新......我试图简化我正在尝试创建的更复杂的结构。
  • 我将尝试在您的小提琴上构建案例。不过问题一定出在我从 handleClick() 调用 scoreUpdate() 的过程中。
  • 我不认为this.state.progress.length % 3 == 0 正在做你认为它正在做的事情。 % 用于模数。如果您想在state.progress3 时更新state.score,那么您的逻辑不是:this.state.progress.length === 3?
  • 猜你喜欢
    相关资源
    最近更新 更多
    热门标签