理解React setState的异步性

时间:2018-07-06 00:47:58

标签: javascript reactjs state

我正在编写的React应用程序存在问题,我认为这源于setState()的异步性。我的代码如下:

import React, { Component } from 'react';
import TextInput from './TextInput';
import TextDisplay from './TextDisplay';
import Dropdown from './Dropdown';

const langs = {
arabic: ['ا', 'ب', 'غ', 'ج', 'ذ', 'د', 'ه', 'ة', 'و', 'ز', 
'ح', 'ط', 'ظ', 'ي', 'خ', 'ك', 'ل', 'م', 'ن', 'س', 'ع', 'ف', 
'ص', 'ض', 'ق', 'ر', 'ش', 'س', 'ت', 'ث', 'ّ', 'أُ', 'إ', 'أ', 
'ئ', 'ٍ', 'ً', 'ِ', 'ُ', ' ', '\n'],
judeoArabic: ['א', 'ב', 'ג', 'ג֔', 'ד', 'דּ', 'ה', 'ה֕', 'ו', 'ז', 
'ח', 'ט', 'ט֔', 'י', 'כ', 'כּ', 'ל', 'מ', 'נ', 'ס', 'ע', 'פ', 'צ', 
'צ֔', 'ק', 'ר', 'שׁ', 'ס', 'תּ', 'ת', '֝', 'ו', 'י', 'א', 'אְי', 'ינ', 
'אנ', 'י', 'ו', ' ', '\n']
};

class Home extends Component {
  constructor(props) {
  super(props);
  this.state = {value: '',
  displayValue: '',
  inLang: '',
  outLang: ''
  };

  this.handleChange = this.handleChange.bind(this);
  this.handleSet = this.handleSet.bind(this);
  this.handleClear = this.handleClear.bind(this);
  this.handleInLang = this.handleInLang.bind(this);
  this.handleOutLang = this.handleOutLang.bind(this);
}

handleChange(e) {
  this.setState({value: e.target.value});
}

handleSet(inLang, outLang, letter, indices, display) {
  indices = [];
  display = [];
  inLang = this.state.inLang;
  outLang = this.state.outLang;
  for (var i = 0; i < this.state.value.length; i ++) {
    letter = this.state.value.charAt(i);
    indices.push(langs.inLang.indexOf(letter));
  }
  for (i = 0; i < indices.length; i ++) {
    display.push(langs.outLang[indices[i]]);
  }
  this.setState({displayValue: display.join('')});
}

handleClear() {
  this.setState({displayValue: ''});
}

handleInLang(e) {
  this.setState({inLang: e.target.value});
}

handleOutLang(e) {
  this.setState({outLang: e.target.value});
}

render() {
    return (
        <div className="App">
        <header className="App-header">
        <h1 className="App-title">Judeo-Arabic Transliterator v 2.0</h1>
      </header>
      <p className="App-intro">
        Enter your Hebrew text below, and select the language to see your transliteration
        </p>
      <Dropdown placeholder={'From'} handleChange={this.handleInLang}/>
      <Dropdown placeholder={'To'} handleChange={this.handleOutLang}/>
      <TextInput handleChange={this.handleChange}/>
      <button onClick={this.handleSet}>Transliterate</button>
      <button onClick={this.handleClear}>Clear</button>
      <TextDisplay textDisplay={this.state.displayValue}/>
    </div>
    )
}
}

export default Home;

当我运行开发服务器时,它最初呈现的很好。我可以选择一个下拉项,它是langs变量中声明的语言之一。但是,当我输入一些文本并单击Transliterate按钮时,出现此错误:TypeError: Cannot read property 'indexOf' of undefined。它指的是第44行:indices.push(langs.inLang.indexOf(letter));

我的假设是langs.inLang是不确定的,因为当我从下拉菜单中选择状态时,我已经更新了状态,并且现在正试图访问该状态,就好像它已被更新一样。但是,我不能肯定这是我做错了。如果是这样,那么我对如何处理这种异步性还是有点模糊。非常感谢您的帮助。

此外,如果对我的代码还有其他批评,请随时与我们分享。

1 个答案:

答案 0 :(得分:1)

您需要使用方括号表示法来动态访问对象属性。

indices.push(langs[inLang].indexOf(letter));

类似地:

display.push(langs[outLang][indices[i]]);