我想通过读取JSON文件来实现对话系统,这里是:`
{
"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
最后是将显示文本的Speaking组件
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,但它没有成功。
知道怎么排序吗?谢谢!
答案 0 :(得分:2)
您可以使用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}
/>
);
}
}
然后在Speaking中,只需在消息末尾调用回调
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>
);
}
}