index2.html
<html>
<head>
<meta charset="UTF-8" />
<title>구구단</title>
<script crossorigin src="https://unpkg.com/react@18/umd/react.development.js"></script>
<script crossorigin src="https://unpkg.com/react-dom@18/umd/react-dom.development.js"></script>
<script src="https://unpkg.com/babel-standalone@6/babel.min.js"></script>
</head>
<body>
<div id="root"></div> <!-- 결과: <div id="root"><button>Like</button></div> -->
<script type="text/babel">
// class GuGuDan extedns React.Component {
//
// }
// Hooks : GuGuDan이라는 함수 컴포넌트에 state와 ref기능을 추가해준 것
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(null);
// use로 시작되는 것이 Hooks
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();
}
}
const onChangeInput = (e) => {
setValue(e.target.value);
}
return (
<React.Fragment>
<div>{first} 곱하기 {second}는 ?</div>
<form onSubmit={onSubmitForm}>
<input ref={inputRef} onChange={onChangeInput} value={value}/>
<button>입력!</button>
</form>
<div id="result">{result}</div>
</React.Fragment>
);
}
</script>
<script type="text/babel">
ReactDOM.createRoot(document.querySelector('#root')).render(<div><GuGuDan/></div>);
</script>
</body>
</html>
Class
Gugudan-class.html
<html>
<head>
<meta charset="UTF-8"/>
<title>구구단</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> <!-- 결과: <div id="root"><button>Like</button></div> -->
<script type="text/babel">
class GuGuDan extends React.Component {
state = {
first: Math.ceil(Math.random() * 9),
second: Math.ceil(Math.random() * 9),
value: '',
result: '',
};
onSubmit = (e) => {
e.preventDefault();
if (parseInt(this.state.value) === this.state.first * this.state.second) {
this.setState((prevState) => {
return {
result: '정답: ' + prevState.value, // 정답 값 표시하기 (현재 값) => 현재 state
first: Math.ceil(Math.random() * 9),
second: Math.ceil(Math.random() * 9),
value: '',
// => 미래 state
};
});
this.input.focus();
} else {
this.setState({
result: '땡',
value: '',
});
this.input.focus();
}
};
onChange = (e) => {
this.setState({ value: e.target.value });
};
input;
onRefInput = (c) => { this.input = c; };
// => 함수를 렌더링할 때 마다 만들면 낭비이기 때문에 함수를 따로 빼는 것이 좋다.
// 컨텐츠
render() {
console.log('렌더링'); // setState를 할 때마다 render 함수가 실행된다.
return (
<React.Fragment>
<div>{this.state.first} 곱하기 {this.state.second}는?</div>
<form onSubmit={this.onSubmit}>
<input ref={this.onRefInput} type="number" value={this.state.value} onChange={this.onChange}/>
<button>입력!</button>
{/* <button id="button" className="" htmlFor="">입력!</button> */}
{/* id 사용 가능 */}
{/* class : React에서는 class대신 className을 사용해야한다. -> React class랑 헷갈려서 */}
{/* label의 for 속성 : for대신 htmlFor을 써야한다. -> 반복문의 for과 헷갈린다. */}
</form>
<div>{this.state.result}</div>
</React.Fragment>
);
}
}
</script>
<script type="text/babel">
ReactDOM.render(<GuGuDan/>, document.querySelector('#root'));
</script>
</body>
</html>
Hooks
index2.html
<html>
<head>
<meta charset="UTF-8" />
<title>구구단</title>
<script crossorigin src="https://unpkg.com/react@18/umd/react.development.js"></script>
<script crossorigin src="https://unpkg.com/react-dom@18/umd/react-dom.development.js"></script>
<script src="https://unpkg.com/babel-standalone@6/babel.min.js"></script>
</head>
<body>
<div id="root"></div> <!-- 결과: <div id="root"><button>Like</button></div> -->
<script type="text/babel">
// class GuGuDan extedns React.Component {
//
// }
// Hooks : GuGuDan이라는 함수 컴포넌트에 state와 ref기능을 추가해준 것
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(null);
// use로 시작되는 것이 Hooks
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();
}
}
const onChangeInput = (e) => {
setValue(e.target.value);
}
console.log('렌더링');
return (
<React.Fragment>
<div>{first} 곱하기 {second}는 ?</div>
<form onSubmit={onSubmitForm}>
<input ref={inputRef} onChange={onChangeInput} value={value}/>
<button>입력!</button>
</form>
<div id="result">{result}</div>
</React.Fragment>
);
}
</script>
<script type="text/babel">
ReactDOM.createRoot(document.querySelector('#root')).render(<div><GuGuDan/></div>);
</script>
</body>
</html>
node랑 npm 설치하기
터미널에서 폴더 위치 설정하고 npm init 치기
package name, author(이름), license(MIT, ISTC) 설정
-> package.jsc 생성 : 리액트 개발에 필요한 모든 패키지를 넣는 곳
npm i react react-dom : react랑 react-dom 설치
npm i -D webpack webpack-cli : 리액트할 때 필요한 webpack과 webpack-cli 설치
실제 서비스에서 사용되는 것들
dependencies에 기록
개발할 때만 사용되는 것들
devDependencies에 기록
module.exports = {
속성들 넣기
};
const React = require('react');
const ReactDom = require('react-dom');
-> react와 react-dom 불러오기
ReactDom.render(<WordRelay />, document.querySelector('#root'));
<html>
<head>
<meta charset="UTF-8" />
<title>끝말잇기</title>
</head>
<body>
<div id="root"></div>
<script src="./dist/app.js"></script>
</body>
</html>
client.jsx
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 {Component} = React;
class WordRelay extends Component {
state = {
};
render() {
}
}
module.exports = WordRelay;
// 파일을 나눌 때는 const..와 modul..e을 추가적으로 적어준다.
webpack.config.js
// 파일을 하나로 합쳐주는 역할을 함
const path = require('path'); // 경로 조작
module.exports = {
name: 'wordrelay-setting', // 불필요하지만 속성같은 느낌 : 웹팩에 대한 설명
mode: 'development', // 실서비스: production
devtool: 'eval', // 빠르게 하겠다는 뜻
resolve: {
extensions: ['.js', '.jsx']
// 이렇게 하면 확장자를 일일이 쓸 필요 없이 알아서 찾아준다.
},
entry: {
app: ['./client'],
//app: ['./client.jsx', 'WordRelay.jsx'] -> client.jsx에서 이미 WordRelay.jsx를 불러오고 있기 때문에 굳이 또 적지 않아도 된다.
}, // 입력 (ex. client.jsx, WordRelay.jsx)
output: {
path: path.join(__dirname, 'dist'), // -> 현재 폴더 안에 있는 dist 폴더
// path.join : 경로를 합쳐줌
// __dirname : 현재 폴더 경로
filename: 'app.js'
}, // 출력 (ex. app.js)
};
// -> 이러고 터미널에 webpack을 치면 파일을 하나로 합친다.
babel 설치 (개발용에서만 사용)
webpack.config.js
// 파일을 하나로 합쳐주는 역할을 함
const path = require('path'); // 경로 조작
module.exports = {
name: 'wordrelay-setting', // 불필요하지만 속성같은 느낌 : 웹팩에 대한 설명
mode: 'development', // 실서비스: production
devtool: 'eval', // 빠르게 하겠다는 뜻
resolve: {
extensions: ['.js', '.jsx']
// 이렇게 하면 확장자를 일일이 쓸 필요 없이 알아서 찾아준다.
},
entry: {
app: ['./client'],
//app: ['./client.jsx', 'WordRelay.jsx'] -> client.jsx에서 이미 WordRelay.jsx를 불러오고 있기 때문에 굳이 또 적지 않아도 된다.
}, // 입력 (ex. client.jsx, WordRelay.jsx)
module: {
rules: [{
test: /\.jsx?/, // js파일과 jsx파일을 이 rule을 적용하겠다는 뜻 (정규 표현식)
loader: 'babel-loader', // babel rule
options: {
presets: ['@babel/preset-env', '@babel/preset-react'], // 알아서 js나 jsx 파일에 babel을 적용해준다.
plugins: ['@babel/plugin-proposal-class-properties'],
},
}],
}, // -> entry에 있는 파일을 읽고 거기에 module을 적용한 후, output에 뺀다.
output: {
path: path.join(__dirname, 'dist'), // -> 현재 폴더 안에 있는 dist 폴더
// path.join : 경로를 합쳐줌
// __dirname : 현재 폴더 경로
filename: 'app.js'
}, // 출력 (ex. app.js)
};
// -> 이러고 터미널에 webpack을 치면 파일을 하나로 합친다.
WordRelay.jsx
const React = require('react');
const {Component} = React;
class WordRelay extends Component {
state = {
text: 'Hello, webpack',
};
render() {
return <h1>{this.state.text}</h1>
}
}
module.exports = WordRelay;
// 파일을 나눌 때는 const..와 modul..e을 추가적으로 적어준다.
Inflearn - 웹 게임을 만들며 배우는 React (조현영 (제로초))