2017-07-30 63 views
0

延遲我想通過讀取JSON文件來實現對話系統,那就是:'的setState在ReactJS

{ 
    "start": { 
     "dialogue1": { 
     "text": "Hi! How are you?" 
     }, 
     "dialogue2": { 
     "text": "My name is Bill." 
     }, 
     "dialogue3": { 
     "text": "What is your name?" 
     }, 
     "dialogue4": { 
     "text": "Nice to meet you" 
     } 
    } 
} 

這裏是讀取JSON文件中的分量:

import React, { Component } from 'react' 
import Speaking from './Speaking' 
import dialogues from './dialogues/dialogues.json'; 


class myClass extends Component { 
    constructor(props) { 
    super(props); 
    this.goToDialogue = this.goToDialogue.bind(this) 

    //starts with empty dialogue 
    this.state = { 
     dialogue: '' 
    }; 
    } 

    componentDidMount() { 
    //starts first dialogue at the beginning 
    this.goToDialogue('start') 
    } 

    goToDialogue(dialogueName) { 
    //loop through dialogue JSON and update the state 
    for (let dialogue in dialogues[dialogueName]) { 
     this.setState({dialogue : dialogues[dialogueName][dialogue].text}) 
    } 
    } 

    render() { 
    return (
     //give Speaking's component the new dialogue to display 
     <Speaking dialogue={this.state.dialogue} /> 
    ); 
    } 

} 

export default myClass 

最後,將顯示的文本

import React, { Component } from 'react'; 

class Speaking extends Component { 
    constructor(props) { 
    super(props); 
    this.showText = this.showText.bind(this) 
    } 

    componentDidUpdate() { 
    //showText() will display the message it receives into the paragraph letter by letter 
    this.showText(this.props.dialogue, 0, 75) 
    } 

    showText(message, index, interval) { 
    if (index < message.length) { 
     this.speak.innerHTML += message[index++] 
     setTimeout(() => { this.showText(message, index, interval); }, interval) 
    } 
    } 

    render() { 

    return (
     <p className="speak" ref={node => this.speak = node} ></p> 
    ); 
    } 
} 

export default Speaking; 

問題口語組分是myClass.state.dialogue將被饋送最後一個循環迭代,所以它只會顯示最後一個對話框。 我想要的正確結果是在每次迭代之間延遲一個一個顯示每個對話行(換句話說,setState對話)。我想過在setState上使用setTimeOut,但沒有成功。

任何想法如何排序?謝謝!

回答

1

您也許可以使用Speaking組件的回調來知道當前對話已被完全說出。

class myClass extends Component { 
    constructor(props) { 
    super(props); 
    this.goToDialogue = this.goToDialogue.bind(this) 
    this.handleHasSpoken = this.handleHasSpoken.bind(this); 

    //starts with empty dialogue 
    this.state = { 
     dialogue: '', 
     dialogueIndex: 0 
    }; 
    } 

    componentDidMount() { 
    //starts first dialogue at the beginning 
    this.goToDialogue('start') 
    } 

    goToDialogue(dialogueName) { 
    const { dialogueIndex } = this.state; 
    this.setState({ dialogue: dialogues[dialogueName][dialogueIndex].text }); 
    } 

    handleHasSpoken() { 
    const { dialogueIndex } = this.state; 

    //insert logic to check if last dialogue 
    this.setState({ 
     dialogueIndex: dialogueIndex+1, 
     dialogue: dialogues[dialogueName][dialogueIndex+1] 
    }); 
    } 

    render() { 
    return (
     //give Speaking's component the new dialogue to display 
     <Speaking 
      dialogue={this.state.dialogue} 
      hasSpoken={this.handleHasSpoken} 
     /> 
    ); 
    } 

} 

,然後在說起,只是調用回調在郵件的結尾,當

class Speaking extends Component { 
    constructor(props) { 
    super(props); 
    this.showText = this.showText.bind(this) 
    } 

    componentDidUpdate() { 
    //showText() will display the message it receives into the paragraph letter by letter 
    this.showText(this.props.dialogue, 0, 75) 
    } 

    showText(message, index, interval) { 
    if (index < message.length) { 
     this.speak.innerHTML += message[index++] 
     setTimeout(() => { this.showText(message, index, interval); }, interval) 
    } else { 
     this.props.hasSpoken(); 
    } 
    } 

    render() { 

    return (
     <p className="speak" ref={node => this.speak = node} ></p> 
    ); 
    } 
}