在ReactJS中设置带延迟的状态
我想通过读取JSON文件来实现一个对话系统,如下所示:`在ReactJS中设置带延迟的状态,reactjs,setstate,Reactjs,Setstate,我想通过读取JSON文件来实现一个对话系统,如下所示:` { "start": { "dialogue1": { "text": "Hi! How are you?" }, "dialogue2": { "text": "My name is Bill." }, "dialogue3": { "text": "What is your name?" }, "d
{
"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}来自“React”
从“/正在讲话”导入讲话
从“./dialogs/dialogs.json”导入对话;
类myClass扩展组件{
建造师(道具){
超级(道具);
this.goToDialogue=this.goToDialogue.bind(this)
//从空洞的对话开始
此.state={
对话:''
};
}
componentDidMount(){
//开始第一段对话
this.goToDialogue('start'))
}
goToDialogue(dialogueName){
//循环对话JSON并更新状态
for(让对话成为对话[dialogueName]){
this.setState({dialogue:dialogs[dialogueName][dialogue].text})
}
}
render(){
返回(
//将要显示的新对话交给Speaking的组件
);
}
}
导出默认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;
import React,{Component}来自'React';
类扩展组件{
建造师(道具){
超级(道具);
this.showText=this.showText.bind(this)
}
componentDidUpdate(){
//showText()会将收到的消息逐字显示到段落中
this.showText(this.props.dialogue,0,75)
}
showText(消息、索引、间隔){
if(索引<消息长度){
this.speak.innerHTML++=消息[index++]
setTimeout(()=>{this.showText(消息,索引,间隔);},间隔)
}
}
render(){
返回(
this.speak=node}>
);
}
}
导出默认会话;
问题是myClass.state.dialogue将与最后一个循环迭代一起提供,因此它将只显示最后一个对话行我想要的正确结果是在每次迭代之间延迟一行一行地显示每个对话(换句话说,设置对话状态)。我曾想过在setState上使用setTimeOut,但没有成功
你知道怎么解决吗?谢谢 您可以使用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 myClass扩展组件{
建造师(道具){
超级(道具);
this.goToDialogue=this.goToDialogue.bind(this)
this.handleHasSpoken=this.handleHasSpoken.bind(this);
//从空洞的对话开始
此.state={
对话:“,
对话框索引:0
};
}
componentDidMount(){
//开始第一段对话
this.goToDialogue('start'))
}
goToDialogue(dialogueName){
const{dialogueIndex}=this.state;
this.setState({dialogue:dialogs[dialogueName][dialogueIndex].text});
}
handleHasSpoken(){
const{dialogueIndex}=this.state;
//插入逻辑以检查是否存在最后一个对话
这个.setState({
dialogueIndex:dialogueIndex+1,
对话:对话[dialogueName][dialogueIndex+1]
});
}
render(){
返回(
//将要显示的新对话交给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>
);
}
}
类扩展组件{
建造师(道具){
超级(道具);
this.showText=this.showText.bind(this)
}
componentDidUpdate(){
//showText()会将收到的消息逐字显示到段落中
this.showText(this.props.dialogue,0,75)
}
showText(消息、索引、间隔){
if(索引<消息长度){
this.speak.innerHTML++=消息[index++]
setTimeout(()=>{this.showText(消息,索引,间隔);},间隔)
}否则{
this.props.hasSpoken();
}
}
render(){
返回(
this.speak=node}>
);
}
}
您可以使用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 myClass扩展组件{
建造师(道具){
超级(道具);
this.goToDialogue=this.goToDialogue.bind(this)
this.handleHasSpoken=this.handleHasSpoken.bind(this);
//从空洞的对话开始
此.state={
对话:“,
对话框索引:0
};
}
componentDidMount(){
//开始第一段对话
this.goToDialogue('start'))
}
goToDialogue(dialogueName){
const{dialogueIndex}=this.state;
this.setState({dialogue:dialogs[dialogueName][dialogueIndex].text});
}
handleHasSpoken(){
const{dialogueIndex}=this.state;
//插入逻辑以检查是否存在最后一个对话
这个.setState({
dialogueIndex:dialogueIndex+1,
对话:对话[dialogueName][dialogueIndex+1]
});
}
render(){
返回(
//将要显示的新对话交给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>
);
}
}
类扩展组件{
建造师(道具){
超级(道具);
this.showText=this.showText.bind(this)
}
componentDidUpdate(){
//showText()会将收到的消息逐字显示到段落中
this.showText(this.props.dialogue,0,75)
}
showText(消息、索引、间隔){
if(索引<消息长度){
this.speak.innerHTML++=消息[index++]
setTimeout(()=>{this.showText(消息,索引,间隔);},间隔)
}否则{
this.props.hasSpoken();
}
}
render(){
返回(
this.speak=node}>
);
}
}