Reactを使用したオンラインゲームの接続
112677 ワード
この文章は「[オンラインゲームの作成と学習のインタラクション]」課のまとめです.
1.React Hooksが登場したきっかけ
Webパッケージを使用して1番コードを実行するコードを教えてください.
Webパッケージを使用して、次の文字ジャッキーコードを作成します(Hooksを使用します).
Webパッケージを使用して、次の文字ジャッキーコードを作成します(Classを使用してください)
6.さらに考える
1番正解 2番正しいお客様に回答します.jsx 3番正解クライアント.jsx 4番正しいお客様に回答します.jsx
1.React Hooksが登場したきっかけ
既存のReactでは、以下のように関数型を使用する場合、クラスのsetStateまたはstateは使用できないため、setStateまたはstateを使用しない構文にのみ使用されます.const GuGuDan = () => {
return <div>Hello, Hooks</div>;
}
しかし、関数型内でstateを使用することがますます要求されるにつれて、Reactは関数型素子内でstateを使用することを改善した.それがいわゆる「React Hooks」です.クラスコンポーネントベースのレスポンスコードを中心としていたが、最近ではレスポンス式ドキュメントでクラスコンポーネントを使用するのではなく、Hooksを使用することを推奨している.Hooksの基本フォーマットは次のとおりです.// 아래 코드는 웹팩을 사용했다고 가정한 코드이다.
const GuGuDan = () => {
const [first, setFirst] = useState(Math.ceil(Math.random()*9));
const [second, setSecond] = useState(Math.ceil(Math.random()*9));
// 필요한 추가적인 state들 작성
return (
<>
<div>{first}곱하기{second}는?</div>
</>
);
}
2.Refの使い方
Refの場合、クラスとHooksの使い方が異なることに注意してください.
2.1.クラス構成部品のRef
(1)const onRefInput = (c) => { this.taewoong = c }
this.taewoong.focus();
<input ref={ this.onRefInput } ... />
(2)import { createRef } from 'react';
inputRef = createRef();
this.inputRef.current.focus();
<input ref={this.inputRef} ... />
第2の方法と同様に、クラスのrefはHooksのrefと同様に使用することができる.ただし、2つ目の方法と同じ方法ではrefに他のアクションを追加することはできません.そのため、refをより詳細に利用したい場合は、(1)の方法でrefを作成できます.
2.2.HooksのRef
const React = require('react');
const { useRef } = React;
const inputRef = useRef(null);
inputRef.current.focus();
<input ref={ inputRef } ... />
HooksのRefについては、一般値を記憶する方法もあるが、後述する.
3.Hooksの再読み込み
以前に符号化されたclass gudan素子をhooksに変換し、以下に示す.const React = require('react');
const { useState, useRef } = React;
const GuGuDan = () => {
const [first, setFirst] = useState(Math.ceil(Math.random() * 9));
const [second, setSecond] = useState(Math.ceil(Math.random() * 9));
const [value, setValue] = useState('');
const [result, setResult] = useState('');
const inputRef = useRef();
const onChangeInput = (e) => {
setValue(e.target.value);
};
const onSubmitForm = (e) => {
e.preventDefault();
if(parseInt(value) === first * second){
setResult('정답: ' + value);
setFirst(Math.ceil(Math.random() * 9));
setSecond(Math.ceil(Math.random() * 9));
setValue('');
inputRef.current.focus();
} else {
setResult('떙');
setValue('');
inputRef.current.focus();
}
}
return <>
<div>{first}곱하기{second}는?</div>
<form onSubmit={onSubmitForm}>
<input ref={inputRef} type="number" onChange={onChangeInput} value={value} />
<button>입력!</button>
</form>
<div id="result">{result}</div>
</>
}
module.exports = GuGuDan;
デフォルトでは、Hooksはステータスの変更に伴って再ロードされ、矢印関数のすべての部分が再ロードされます.すなわち、class素子に比べて、再ロード時に関数全体が再生成されるため、速度が遅くなる可能性があります.stateが変更されるたびに再ロードされる場合は、次のような状況ですか?下記のstateは4回交換していますので、4回再ロードできますか?const onSubmitForm = (e) => {
e.preventDefault();
if(parseInt(value) === first * second){
**setResult('정답: ' + value);
setFirst(Math.ceil(Math.random() * 9));
setSecond(Math.ceil(Math.random() * 9));
setValue('');**
inputRef.current.focus();
} else {
setResult('떙');
setValue('');
inputRef.current.focus();
}
}
答えは「いいえ」です.classコンポーネントでもそうですが、userStateクラス(上のsetResult、setFirstなど)は非同期関数です.したがって、パラレル実行なので、4回stateを変更しても1回しかレンダリングできません....
<body>
<div id="root"></div>
<script type="text/babel">
const e = React.createElement;
class Taewoong extends React.Component {
state = {
c: 0,
};
onClick = () => {
this.setState({
c: this.state.c + 1,
});
this.setState({
c: this.state.c + 1,
});
this.setState({
c: this.state.c + 1,
});
};
render() {
return (
<React.Fragment>
<button onClick={this.onClick}>{this.state.c}</button>
</React.Fragment>
);
}
}
</script>
<script type="text/babel">
ReactDOM.render(<Taewoong />, document.querySelector('#root'));
</script>
</body>
たとえば、上のコードのようにsetStateと書くと、cは3になる可能性がありますが、setStateは並列に実行されるため、3にはならず、1になる可能性もあります.
4.Webパッケージとは何か&Webパッケージとホットロードの使い方
Webパッケージは、最新のフロントエンドフレームワークで最も一般的なモジュールバンドルパッケージです.モジュールバンドルパッケージとは、Webアプリケーションを構成するすべてのリソース(HTML、CSS、JavaScript、Imagesなど)を各モジュールと見なし、それらを組み合わせて結果を作成するツールです.
簡単に言えば、Webパッケージを使う理由は以下の通りです!
簡単にするために、フェイスブックを例に挙げましょう.Facebookには2万個を超えるコンポーネント(JavaScript)があるそうです.では、この2万個の素子を1ページにまとめるにはどうすればいいのでしょうか.この機能を実現するのがWebパッケージです.構成部品を結合し、重複を除去し、babelを適用します.
Webパッケージとホットロードの使用
(1)ノードを敷く.
(2)npm initでパッケージ化する.jsonの生成
(3) npm i react react-dom
(4) npm i -D webpack webpack-cli
(5)npx webpackでwebpackを実行できる.
(6)ただし,webpackでJSXを使用するには,以下のbabelに関するモジュールをインストールする必要がある.
(7) npm i -D @babel/core @babel/preset-env @babel/preset-react babel-loader
(8)以降のwebpack.config.js設定(以下で整理)
(9) package.jsonの「scripts」は以下のように設定され、num run devホットロードを使用します.// package.json
{
"name": "webpackgo",
"version": "1.0.0",
"description": "",
"main": "index.js",
***"scripts": {
"dev": "webpack"
},***
"author": "taewoong",
"license": "MIT",
"dependencies": {
"react": "^17.0.2",
"react-dom": "^17.0.2"
},
"devDependencies": {
"@babel/core": "^7.14.6",
"@babel/preset-env": "^7.14.7",
"@babel/preset-react": "^7.14.5",
"babel-loader": "^8.2.2",
"webpack": "^5.44.0",
"webpack-cli": "^4.7.2"
}
}
webpack.config.jsの基本設定は以下の通りです.Webpack 5バージョンに変更すると、いくつかの設定が変わりますのでご注意ください!const path = require('path');
const webpack = require('webpack');
module.exports = {
mode: 'development',
devtool: 'inline-source-map', // hidden-source-map
resolve: {
extensions: ['.jsx', '.js'],
},
entry: {
app: './client',
// 나중에 app: ['./client.jsx', './csas.css', './asdadaf.json'],
// 와 같이 여러 형식의 파일들을 app.js에 하나로 합쳐줄 수 있는데,
// 파일명을 일일이 쓰기 귀찮다면 위에 resolve: {}에 확장자명을 넣어주면 된다.
// 그럼 알아서 웹팩에서 각각의 확장자명의 파일들을 찾아준다.
},
module: {
rules: [{
test: /\.jsx?$/,
loader: 'babel-loader',
options: {
presets: [
['@babel/preset-env', {
targets: {
browsers: ['> 1% in KR'], // browserslist
// 원하는 브라우저 버전에만 바벨을 적용할 수도 있다.
// 많은 브라우저를 지원할수록 속도가 그만큼 느려지기 때문
// 위 코드는 한국에서 5% 이상 지원하는 브라우저를 타겟으로 하는 것이다.
// https://github.com/browserslist/browserslist
// 위 주소에서 더 자세한 정보를 확인할 수 있다.
},
debug: true,
}],
'@babel/preset-react',
],
plugins: [],
},
}],
},
output: {
filename: 'app.js',
path: path.join(__dirname, 'dist'),
},
};
すべて設定が完了すると、以下のようにreactとreact-domが読み込まれます.(1)
import React from 'react';
import ReactDOM from 'react-dom';
(2)
const React = require('react');
const ReactDOM = require('react-dom');
두 방법 모두 가능하다. (1)은 Next.js 쓸 때 자주 쓰고, (2)는 Node.js 쓸 때 자주 쓰는 것 같다.
create-react-appを使用すると、上記の設定は自動的に完了しますが、create-react-appを最初から使用すると、プロセスが正確に理解できません.このように自分で勉強してからCRAを書いたほうがいいです.
5.復習問題(答えは下)
次のgugugudanコンポーネントを作成するコードを作成してください.(Hooksを使用)
const GuGuDan = () => {
return <div>Hello, Hooks</div>;
}
// 아래 코드는 웹팩을 사용했다고 가정한 코드이다.
const GuGuDan = () => {
const [first, setFirst] = useState(Math.ceil(Math.random()*9));
const [second, setSecond] = useState(Math.ceil(Math.random()*9));
// 필요한 추가적인 state들 작성
return (
<>
<div>{first}곱하기{second}는?</div>
</>
);
}
Refの場合、クラスとHooksの使い方が異なることに注意してください.
2.1.クラス構成部品のRef
(1)
const onRefInput = (c) => { this.taewoong = c }
this.taewoong.focus();
<input ref={ this.onRefInput } ... />
(2)import { createRef } from 'react';
inputRef = createRef();
this.inputRef.current.focus();
<input ref={this.inputRef} ... />
第2の方法と同様に、クラスのrefはHooksのrefと同様に使用することができる.ただし、2つ目の方法と同じ方法ではrefに他のアクションを追加することはできません.そのため、refをより詳細に利用したい場合は、(1)の方法でrefを作成できます.2.2.HooksのRef
const React = require('react');
const { useRef } = React;
const inputRef = useRef(null);
inputRef.current.focus();
<input ref={ inputRef } ... />
HooksのRefについては、一般値を記憶する方法もあるが、後述する.3.Hooksの再読み込み
以前に符号化されたclass gudan素子をhooksに変換し、以下に示す.const React = require('react');
const { useState, useRef } = React;
const GuGuDan = () => {
const [first, setFirst] = useState(Math.ceil(Math.random() * 9));
const [second, setSecond] = useState(Math.ceil(Math.random() * 9));
const [value, setValue] = useState('');
const [result, setResult] = useState('');
const inputRef = useRef();
const onChangeInput = (e) => {
setValue(e.target.value);
};
const onSubmitForm = (e) => {
e.preventDefault();
if(parseInt(value) === first * second){
setResult('정답: ' + value);
setFirst(Math.ceil(Math.random() * 9));
setSecond(Math.ceil(Math.random() * 9));
setValue('');
inputRef.current.focus();
} else {
setResult('떙');
setValue('');
inputRef.current.focus();
}
}
return <>
<div>{first}곱하기{second}는?</div>
<form onSubmit={onSubmitForm}>
<input ref={inputRef} type="number" onChange={onChangeInput} value={value} />
<button>입력!</button>
</form>
<div id="result">{result}</div>
</>
}
module.exports = GuGuDan;
デフォルトでは、Hooksはステータスの変更に伴って再ロードされ、矢印関数のすべての部分が再ロードされます.すなわち、class素子に比べて、再ロード時に関数全体が再生成されるため、速度が遅くなる可能性があります.stateが変更されるたびに再ロードされる場合は、次のような状況ですか?下記のstateは4回交換していますので、4回再ロードできますか?const onSubmitForm = (e) => {
e.preventDefault();
if(parseInt(value) === first * second){
**setResult('정답: ' + value);
setFirst(Math.ceil(Math.random() * 9));
setSecond(Math.ceil(Math.random() * 9));
setValue('');**
inputRef.current.focus();
} else {
setResult('떙');
setValue('');
inputRef.current.focus();
}
}
答えは「いいえ」です.classコンポーネントでもそうですが、userStateクラス(上のsetResult、setFirstなど)は非同期関数です.したがって、パラレル実行なので、4回stateを変更しても1回しかレンダリングできません....
<body>
<div id="root"></div>
<script type="text/babel">
const e = React.createElement;
class Taewoong extends React.Component {
state = {
c: 0,
};
onClick = () => {
this.setState({
c: this.state.c + 1,
});
this.setState({
c: this.state.c + 1,
});
this.setState({
c: this.state.c + 1,
});
};
render() {
return (
<React.Fragment>
<button onClick={this.onClick}>{this.state.c}</button>
</React.Fragment>
);
}
}
</script>
<script type="text/babel">
ReactDOM.render(<Taewoong />, document.querySelector('#root'));
</script>
</body>
たとえば、上のコードのようにsetStateと書くと、cは3になる可能性がありますが、setStateは並列に実行されるため、3にはならず、1になる可能性もあります.
4.Webパッケージとは何か&Webパッケージとホットロードの使い方
Webパッケージは、最新のフロントエンドフレームワークで最も一般的なモジュールバンドルパッケージです.モジュールバンドルパッケージとは、Webアプリケーションを構成するすべてのリソース(HTML、CSS、JavaScript、Imagesなど)を各モジュールと見なし、それらを組み合わせて結果を作成するツールです.
簡単に言えば、Webパッケージを使う理由は以下の通りです!
簡単にするために、フェイスブックを例に挙げましょう.Facebookには2万個を超えるコンポーネント(JavaScript)があるそうです.では、この2万個の素子を1ページにまとめるにはどうすればいいのでしょうか.この機能を実現するのがWebパッケージです.構成部品を結合し、重複を除去し、babelを適用します.
Webパッケージとホットロードの使用
(1)ノードを敷く.
(2)npm initでパッケージ化する.jsonの生成
(3) npm i react react-dom
(4) npm i -D webpack webpack-cli
(5)npx webpackでwebpackを実行できる.
(6)ただし,webpackでJSXを使用するには,以下のbabelに関するモジュールをインストールする必要がある.
(7) npm i -D @babel/core @babel/preset-env @babel/preset-react babel-loader
(8)以降のwebpack.config.js設定(以下で整理)
(9) package.jsonの「scripts」は以下のように設定され、num run devホットロードを使用します.// package.json
{
"name": "webpackgo",
"version": "1.0.0",
"description": "",
"main": "index.js",
***"scripts": {
"dev": "webpack"
},***
"author": "taewoong",
"license": "MIT",
"dependencies": {
"react": "^17.0.2",
"react-dom": "^17.0.2"
},
"devDependencies": {
"@babel/core": "^7.14.6",
"@babel/preset-env": "^7.14.7",
"@babel/preset-react": "^7.14.5",
"babel-loader": "^8.2.2",
"webpack": "^5.44.0",
"webpack-cli": "^4.7.2"
}
}
webpack.config.jsの基本設定は以下の通りです.Webpack 5バージョンに変更すると、いくつかの設定が変わりますのでご注意ください!const path = require('path');
const webpack = require('webpack');
module.exports = {
mode: 'development',
devtool: 'inline-source-map', // hidden-source-map
resolve: {
extensions: ['.jsx', '.js'],
},
entry: {
app: './client',
// 나중에 app: ['./client.jsx', './csas.css', './asdadaf.json'],
// 와 같이 여러 형식의 파일들을 app.js에 하나로 합쳐줄 수 있는데,
// 파일명을 일일이 쓰기 귀찮다면 위에 resolve: {}에 확장자명을 넣어주면 된다.
// 그럼 알아서 웹팩에서 각각의 확장자명의 파일들을 찾아준다.
},
module: {
rules: [{
test: /\.jsx?$/,
loader: 'babel-loader',
options: {
presets: [
['@babel/preset-env', {
targets: {
browsers: ['> 1% in KR'], // browserslist
// 원하는 브라우저 버전에만 바벨을 적용할 수도 있다.
// 많은 브라우저를 지원할수록 속도가 그만큼 느려지기 때문
// 위 코드는 한국에서 5% 이상 지원하는 브라우저를 타겟으로 하는 것이다.
// https://github.com/browserslist/browserslist
// 위 주소에서 더 자세한 정보를 확인할 수 있다.
},
debug: true,
}],
'@babel/preset-react',
],
plugins: [],
},
}],
},
output: {
filename: 'app.js',
path: path.join(__dirname, 'dist'),
},
};
すべて設定が完了すると、以下のようにreactとreact-domが読み込まれます.(1)
import React from 'react';
import ReactDOM from 'react-dom';
(2)
const React = require('react');
const ReactDOM = require('react-dom');
두 방법 모두 가능하다. (1)은 Next.js 쓸 때 자주 쓰고, (2)는 Node.js 쓸 때 자주 쓰는 것 같다.
create-react-appを使用すると、上記の設定は自動的に完了しますが、create-react-appを最初から使用すると、プロセスが正確に理解できません.このように自分で勉強してからCRAを書いたほうがいいです.
5.復習問題(答えは下)
次のgugugudanコンポーネントを作成するコードを作成してください.(Hooksを使用)
const React = require('react');
const { useState, useRef } = React;
const GuGuDan = () => {
const [first, setFirst] = useState(Math.ceil(Math.random() * 9));
const [second, setSecond] = useState(Math.ceil(Math.random() * 9));
const [value, setValue] = useState('');
const [result, setResult] = useState('');
const inputRef = useRef();
const onChangeInput = (e) => {
setValue(e.target.value);
};
const onSubmitForm = (e) => {
e.preventDefault();
if(parseInt(value) === first * second){
setResult('정답: ' + value);
setFirst(Math.ceil(Math.random() * 9));
setSecond(Math.ceil(Math.random() * 9));
setValue('');
inputRef.current.focus();
} else {
setResult('떙');
setValue('');
inputRef.current.focus();
}
}
return <>
<div>{first}곱하기{second}는?</div>
<form onSubmit={onSubmitForm}>
<input ref={inputRef} type="number" onChange={onChangeInput} value={value} />
<button>입력!</button>
</form>
<div id="result">{result}</div>
</>
}
module.exports = GuGuDan;
const onSubmitForm = (e) => {
e.preventDefault();
if(parseInt(value) === first * second){
**setResult('정답: ' + value);
setFirst(Math.ceil(Math.random() * 9));
setSecond(Math.ceil(Math.random() * 9));
setValue('');**
inputRef.current.focus();
} else {
setResult('떙');
setValue('');
inputRef.current.focus();
}
}
...
<body>
<div id="root"></div>
<script type="text/babel">
const e = React.createElement;
class Taewoong extends React.Component {
state = {
c: 0,
};
onClick = () => {
this.setState({
c: this.state.c + 1,
});
this.setState({
c: this.state.c + 1,
});
this.setState({
c: this.state.c + 1,
});
};
render() {
return (
<React.Fragment>
<button onClick={this.onClick}>{this.state.c}</button>
</React.Fragment>
);
}
}
</script>
<script type="text/babel">
ReactDOM.render(<Taewoong />, document.querySelector('#root'));
</script>
</body>
Webパッケージは、最新のフロントエンドフレームワークで最も一般的なモジュールバンドルパッケージです.モジュールバンドルパッケージとは、Webアプリケーションを構成するすべてのリソース(HTML、CSS、JavaScript、Imagesなど)を各モジュールと見なし、それらを組み合わせて結果を作成するツールです.
簡単に言えば、Webパッケージを使う理由は以下の通りです!
簡単にするために、フェイスブックを例に挙げましょう.Facebookには2万個を超えるコンポーネント(JavaScript)があるそうです.では、この2万個の素子を1ページにまとめるにはどうすればいいのでしょうか.この機能を実現するのがWebパッケージです.構成部品を結合し、重複を除去し、babelを適用します.
Webパッケージとホットロードの使用
(1)ノードを敷く.
(2)npm initでパッケージ化する.jsonの生成
(3) npm i react react-dom
(4) npm i -D webpack webpack-cli
(5)npx webpackでwebpackを実行できる.
(6)ただし,webpackでJSXを使用するには,以下のbabelに関するモジュールをインストールする必要がある.
(7) npm i -D @babel/core @babel/preset-env @babel/preset-react babel-loader
(8)以降のwebpack.config.js設定(以下で整理)
(9) package.jsonの「scripts」は以下のように設定され、num run devホットロードを使用します.
// package.json
{
"name": "webpackgo",
"version": "1.0.0",
"description": "",
"main": "index.js",
***"scripts": {
"dev": "webpack"
},***
"author": "taewoong",
"license": "MIT",
"dependencies": {
"react": "^17.0.2",
"react-dom": "^17.0.2"
},
"devDependencies": {
"@babel/core": "^7.14.6",
"@babel/preset-env": "^7.14.7",
"@babel/preset-react": "^7.14.5",
"babel-loader": "^8.2.2",
"webpack": "^5.44.0",
"webpack-cli": "^4.7.2"
}
}
webpack.config.jsの基本設定は以下の通りです.Webpack 5バージョンに変更すると、いくつかの設定が変わりますのでご注意ください!
const path = require('path');
const webpack = require('webpack');
module.exports = {
mode: 'development',
devtool: 'inline-source-map', // hidden-source-map
resolve: {
extensions: ['.jsx', '.js'],
},
entry: {
app: './client',
// 나중에 app: ['./client.jsx', './csas.css', './asdadaf.json'],
// 와 같이 여러 형식의 파일들을 app.js에 하나로 합쳐줄 수 있는데,
// 파일명을 일일이 쓰기 귀찮다면 위에 resolve: {}에 확장자명을 넣어주면 된다.
// 그럼 알아서 웹팩에서 각각의 확장자명의 파일들을 찾아준다.
},
module: {
rules: [{
test: /\.jsx?$/,
loader: 'babel-loader',
options: {
presets: [
['@babel/preset-env', {
targets: {
browsers: ['> 1% in KR'], // browserslist
// 원하는 브라우저 버전에만 바벨을 적용할 수도 있다.
// 많은 브라우저를 지원할수록 속도가 그만큼 느려지기 때문
// 위 코드는 한국에서 5% 이상 지원하는 브라우저를 타겟으로 하는 것이다.
// https://github.com/browserslist/browserslist
// 위 주소에서 더 자세한 정보를 확인할 수 있다.
},
debug: true,
}],
'@babel/preset-react',
],
plugins: [],
},
}],
},
output: {
filename: 'app.js',
path: path.join(__dirname, 'dist'),
},
};
すべて設定が完了すると、以下のようにreactとreact-domが読み込まれます.(1)
import React from 'react';
import ReactDOM from 'react-dom';
(2)
const React = require('react');
const ReactDOM = require('react-dom');
두 방법 모두 가능하다. (1)은 Next.js 쓸 때 자주 쓰고, (2)는 Node.js 쓸 때 자주 쓰는 것 같다.
create-react-appを使用すると、上記の設定は自動的に完了しますが、create-react-appを最初から使用すると、プロセスが正確に理解できません.このように自分で勉強してからCRAを書いたほうがいいです.5.復習問題(答えは下)
次のgugugudanコンポーネントを作成するコードを作成してください.(Hooksを使用)
Webパッケージを使用して1番コードを実行するコードを教えてください.
Webパッケージを使用して、次の文字ジャッキーコードを作成します(Hooksを使用します).
Webパッケージを使用して、次の文字ジャッキーコードを作成します(Classを使用してください)
6.さらに考える
後の概念をもう一度見てから考えます.上図では、ハイライトはレンダリングを意味します.現在のinputウィンドウに数値を入力した場合、inputウィンドウの「2に2を乗じた」または次の「正解」セクションはレンダリングされる必要はありませんが、レンダリングされます.このような状況は、今後のパフォーマンスの問題を引き起こす可能性があります.そこで、これは解決しなければならない問題と考えて、解決策を考えてみましょう.
7.復習問題が正しい
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<script crossorigin src="https://unpkg.com/react@16/umd/react.development.js"></script>
<script crossorigin src="https://unpkg.com/react-dom@16/umd/react-dom.development.js"></script>
<script src="https://unpkg.com/babel-standalone@6/babel.min.js"></script>
</head>
<body>
<div id="root"></div>
<script type="text/babel">
const GuGuDan = () => {
const [first, setFirst] = React.useState(Math.ceil(Math.random()*9));
const [second, setSecond] = React.useState(Math.ceil(Math.random()*9));
const [value, setValue] = React.useState('');
const [result, setResult] = React.useState('');
const inputRef = React.useRef();
const onChangeInput = (e) => {
setValue(e.target.value);
};
const onSubmitForm = (e) => {
e.preventDefault();
if(parseInt(value) === first * second){
setResult('정답: ' + `${first} 곱하기 ${second}는 ${first * second}!`);
setFirst(Math.ceil(Math.random()*9));
setSecond(Math.ceil(Math.random()*9));
setValue('');
inputRef.current.focus();
} else {
setResult('땡');
setValue('');
inputRef.current.focus();
}
}
return <React.Fragment>
<div>{first}곱하기{second}는?</div>
<form onSubmit={onSubmitForm}>
<input ref={inputRef} type="number" onChange={onChangeInput} value={value} />
<button>입력!</button>
</form>
<div>{result}</div>
</React.Fragment>
}
</script>
<script type="text/babel">
ReactDOM.render(<GuGuDan/>, document.querySelector('#root'));
</script>
</body>
</html>
const React = require('react');
const ReactDOM = require('react-dom');
const GuGuDan = require('./GuGuDan');
ReactDOM.render(<GuGuDan/>, document.querySelector('#root'));
GuGuDan.jsx const React = require('react');
const { useState, useRef } = React;
const GuGuDan = () => {
const [first, setFirst] = useState(Math.ceil(Math.random()*9));
const [second, setSecond] = useState(Math.ceil(Math.random()*9));
const [value, setValue] = useState('');
const [result, setResult] = useState('');
const inputRef = useRef();
const onSubmitForm = (e) => {
e.preventDefault();
if(parseInt(value) === first * second){
setResult('정답: ' + `${first} 곱하기 ${second}는 ${first * second}!`);
setFirst(Math.ceil(Math.random()*9));
setSecond(Math.ceil(Math.random()*9));
setValue('');
inputRef.current.focus();
} else {
setResult('땡');
setValue('');
inputRef.current.focus();
}
}
const onChangeInput = (e) => {
setValue(e.target.value);
}
return (
<>
<div>{first}곱하기{second}는?</div>
<form onSubmit={onSubmitForm}>
<input ref={inputRef} type="number" onChange={onChangeInput} value={value} />
<button>입력!</button>
</form>
<div>{result}</div>
</>
)
}
module.exports = GuGuDan;
index.html <!DOCTYPE html>
<html lang="ko">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>GuGuDan</title>
</head>
<body>
<div id="root"></div>
<script src="./dist/app.js"></script>
</body>
</html>
const React = require('react');
const ReactDOM = require('react-dom');
const WordRelay = require('./WordRelay');
ReactDOM.render(<WordRelay/>, document.querySelector('#root'));
WordRelay.jsx const React = require('react');
const { useState, useRef } = React;
const WordRelay = () => {
const [word, setWord] = useState('제로초');
const [value, setValue] = useState('');
const [result, setResult] = useState('');
const inputRef = useRef();
const onSubmitForm = (e) => {
e.preventDefault();
if(word.substr(-1) === value.substr(0,1)){
setWord(value);
setResult('딩동댕');
setValue('');
inputRef.current.focus();
} else {
setResult('땡');
setValue('');
inputRef.current.focus();
}
}
const onChangeInput = (e) => {
setValue(e.target.value);
}
return (
<>
<div>{word}</div>
<form onSubmit={onSubmitForm}>
<label htmlFor="taewoong">글자를 입력하세요 : </label>
<input ref={inputRef} type="text" onChange={onChangeInput} value={value} />
<button>입력!</button>
</form>
<div>{result}</div>
</>
)
}
module.exports = WordRelay;
index.html <!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<div id="root"></div>
<script src="./dist/app.js"></script>
</body>
</html>
const React = require('react');
const ReactDOM = require('react-dom');
const WordRelay = require('./WordRelayClass');
ReactDOM.render(<WordRelayClass/>, document.querySelector('#root'));
WordRelayClass.jsx import React, { Component } from 'react';
class WordRelay extends Component {
state = {
word: '강태웅',
value: '',
result: '',
}
onSubmitForm = (e) => {
e.preventDefault();
if (this.state.word[this.state.word.length-1] === this.state.value[0]) {
this.setState({
word: this.state.value,
value: '',
result: '딩동댕',
});
this.taewoong.focus();
} else {
this.setState({
value: '',
result: '땡',
});
this.taewoong.focus();
}
}
onChangeInput = (e) => {
this.setState({
value: e.target.value,
});
}
onRefInput = (c) => {this.taewoong = c};
render() {
return (
<>
<div>{this.state.word}</div>
<form onSubmit={this.onSubmitForm}>
<input ref={this.onRefInput} type="text" value={this.state.value} onChange={this.onChangeInput} />
<button>입력</button>
</form>
<div>{this.state.result}</div>
</>
);
}
}
export default WordRelay;
index.html <!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<div id="root"></div>
<script src="./dist/app.js"></script>
</body>
</html>
Reference
この問題について(Reactを使用したオンラインゲームの接続), 我々は、より多くの情報をここで見つけました https://velog.io/@ktw2378/React로-끝말잇기-웹게임-구현하기テキストは自由に共有またはコピーできます。ただし、このドキュメントのURLは参考URLとして残しておいてください。
Collection and Share based on the CC Protocol