Reactでタイピンングゲームを作成する際の画面描画のタイミングについて
Reactでタイピングゲーム を作成しているのですが、画面描画のタイミングがうまく行かずに困っています。
下のhtmのコードをブラウザ上で開いてもらうと、
abc
a__
という画面が出てきます。bcとタイプすると、abcと発音するようになっているのですが、cが描画される前にabcと発音し、
終わったらcが描画されるような流れになっています。これを、cが描画された後にabcと発音するように修正したいです。
該当のソースコード
React
1<!DOCTYPE html> 2<html> 3<head> 4 <meta charset="UTF-8" /> 5 <title>React</title> 6 <script src="https://unpkg.com/react@17/umd/react.development.js"></script> 7 <script src="https://unpkg.com/react-dom@17/umd/react-dom.development.js"></script> 8 <script src="https://unpkg.com/@babel/standalone/babel.min.js"></script> 9</head> 10 11<body> 12 <div id="root"></div> 13 <script type="text/babel"> 14 15 (() => { 16 17 class App extends React.Component { 18 constructor() { 19 super(); 20 this.state = { 21 answer: "abc", 22 blank: "a__", 23 location: 1, 24 speak: false, 25 } 26 this.keydown = this.keydown.bind(this) 27 this.speak = this.speak.bind(this) 28 } 29 speak(word) { 30 var speak = new SpeechSynthesisUtterance(); 31 speak.text = word 32 speak.rate = 1.0 33 speak.pitch = 0 34 speak.lang = 'en-US' 35 speechSynthesis.speak(speak) 36 37 let i = 0 38 while (i < 1000000000) 39 i++ 40 } 41 keydown(e) { 42 console.log(e.key) 43 if (this.state.answer[this.state.location] == e.key) { 44 this.setState((state, props) => ({ 45 location: state.location + 1 46 })); 47 let blank = this.state.answer.substring(0, this.state.location) + '_'.repeat(this.state.blank.length - this.state.location); 48 49 this.setState({ 50 blank: blank 51 }) 52 console.log(blank) 53 54 if (this.state.answer.length == this.state.location) { 55 this.setState({ 56 speak: true 57 }) 58 } 59 } 60 } 61 62 componentDidMount() { 63 window.addEventListener('keydown', this.keydown) 64 } 65 66 componentDidUpdate() { 67 if (this.state.speak == true) { 68 this.speak(this.state.answer) 69 } 70 } 71 72 render() { 73 return ( 74 <div> 75 <div> 76 {this.state.answer} 77 </div> 78 <div> 79 {this.state.blank} 80 </div> 81 </div> 82 ); 83 } 84 } 85 86 ReactDOM.render( 87 <App />, 88 document.getElementById('root') 89 ); 90 })(); 91 92 </script> 93</body> 94 95</html>
2021/1/11修正版
React
1 2<!DOCTYPE html> 3<html> 4 5<head> 6 <meta charset="UTF-8" /> 7 <title>React</title> 8 <script src="https://unpkg.com/react@17/umd/react.development.js"></script> 9 <script src="https://unpkg.com/react-dom@17/umd/react-dom.development.js"></script> 10 <script src="https://unpkg.com/@babel/standalone/babel.min.js"></script> 11</head> 12 13<body> 14 <div id="root"></div> 15 <script type="text/babel"> 16 17 (() => { 18 19 class App extends React.Component { 20 constructor() { 21 super(); 22 this.state = { 23 answer: "abc", 24 blank: "a__", 25 location: 1, 26 speaking: undefined, 27 } 28 this.keydown = this.keydown.bind(this) 29 this.speak = this.speak.bind(this) 30 } 31 speak(word) { 32 var speech = new SpeechSynthesisUtterance(word) 33 speechSynthesis.speak(speech) 34 console.log(speechSynthesis) 35 this.setState({ 36 ...this.state, 37 speechSynthesis 38 }) 39 speech.onend = function (event) { 40 console.log(event) 41 console.log(speechSynthesis) 42 } 43 } 44 keydown(e) { 45 console.log(e.key) 46 47 if (this.state.answer[this.state.location] == e.key) { 48 this.setState((state, props) => ({ 49 location: state.location + 1 50 })); 51 let blank = this.state.answer.substring(0, this.state.location) + '_'.repeat(this.state.blank.length - this.state.location); 52 53 this.setState({ 54 blank: blank 55 }) 56 console.log(blank) 57 58 if (this.state.answer.length == this.state.location) { 59 this.speak(this.state.answer) 60 console.log(this.state.speechSynthesis) 61 // while (this.state.speechSynthesis.speaking) 62 this.setState({ 63 ...this.state, 64 answer: "def", 65 blank: "d__", 66 location: 1, 67 }) 68 } 69 } 70 } 71 72 componentDidMount() { 73 window.addEventListener('keydown', this.keydown) 74 } 75 76 render() { 77 return ( 78 <div> 79 <div> 80 {this.state.answer} 81 </div> 82 <div> 83 {this.state.blank} 84 </div> 85 </div> 86 ); 87 } 88 } 89 90 ReactDOM.render( 91 <App />, 92 document.getElementById('root') 93 ); 94 })(); 95 96 </script> 97</body> 98 99</html>
試したこと
componentDidUpdateとフラグの処理などを使って試してみましたが、どのようにしても思うような結果になりません。。
Reactは最後にrender関数で描画していると思うので、そのようになって当然な気もするのですが、何かいい方法はないでしょうか。
render関数が実行された後に実行されるライフルサイクルメソッドのようなものがあればと思ったのですが。。
回答1件
あなたの回答
tips
プレビュー
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
2021/01/10 04:26
2021/01/10 23:14 編集
2021/01/10 16:23
2021/01/10 23:47
2021/01/11 04:08
2021/01/11 06:06
2021/01/11 06:10
2021/01/11 06:39 編集
2021/01/11 06:46
2021/01/11 07:01
2021/01/11 07:56