<!DOCTYPE html>
<html>
<body>
<span>Total Clicks: 0</span>
<button id="btn">Click me</button>
</body>
<script>
let counter = 0;
const button = document.getElementById("btn");
const span = document.querySelector("span");
function handleClick(){
console.log("클릭하였음");
counter += 1;
span.innerText = `Total Clicks: ${counter}`;
}
button.addEventListener("click", handleClick);
</script>
</html><!DOCTYPE html>
<html>
<body>
<div id="root"></div>
</body>
<script src="https://unpkg.com/react@17.0.2/umd/react.production.min.js"></script>
<script src="https://unpkg.com/react-dom@17.0.2/umd/react-dom.production.min.js"></script>
<script>
// 이거 암기할 필요 없음 이렇게 안 함
const root = document.getElementById("root");
const h3 = React.createElement("h3", {
id:"sexy-span", style : {color:"red"}, onMouseEnter : () => console.log("mouse enter")
}, "Hello, I'm a span"); // tag는 HTML에서 쓰는 그대로 작성해야 함
// 우리는 html을 직접 작성하지 않을 것임, react가 작성하도록 하자 interactive하게!
const btn = React.createElement("button", {
onClick: () => console.log("i'm clicked") // 이렇게 eventListener를 작성 가능
}, "Click me");
const container = React.createElement("div", null, [h3,btn]);
ReactDOM.render(container, root); // container를 root 안에 표시하겠다.
</script>
</html>
<!DOCTYPE html>
<html>
<body>
<div id="root"></div>
</body>
<script src="https://unpkg.com/react@17.0.2/umd/react.production.min.js"></script>
<script src="https://unpkg.com/react-dom@17.0.2/umd/react-dom.production.min.js"></script>
<script src="https://unpkg.com/@babel/standalone/babel.min.js"></script>
<script type="text/babel">
// 이거 암기할 필요 없음 이렇게 안 함
const root = document.getElementById("root");
const Title = (
<h3 id="title" onMouseEnter={() => console.log("mouse enter")}>
Hello, I'm a Title
</h3>
); // html과 상당히 유사하게 작성 가능, JSX
const Button = (
<button
style={{ backgroundColor: "tomato" }}
onClick={() => console.log("i'm clicked")}
>
Click me
</button>
);
const container = React.createElement("div", null, [Title, Button]);
ReactDOM.render(container, root); // container를 root 안에 표시하겠다.
</script>
</html><!DOCTYPE html>
<html>
<body>
<div id="root"></div>
</body>
<script src="https://unpkg.com/react@17.0.2/umd/react.production.min.js"></script>
<script src="https://unpkg.com/react-dom@17.0.2/umd/react-dom.production.min.js"></script>
<script src="https://unpkg.com/@babel/standalone/babel.min.js"></script>
<script type="text/babel">
// 이거 암기할 필요 없음 이렇게 안 함
const root = document.getElementById("root");
const Title = () => (
<h3 id="title" onMouseEnter={() => console.log("mouse enter")}>
Hello, I'm a Title
</h3>2
); // html과 상당히 유사하게 작성 가능, JSX
const Button = () => (
<button
style={{ backgroundColor: "tomato" }}
onClick={() => console.log("i'm clicked")}
>
Click me
</button>
);
const Container = () => (<div>
<Title /> <Button />
</div>); // Component의 첫글자는 반드시 대문자여야 함, 소문자면 그냥 html 태그가 돼버림
ReactDOM.render(<Container />, root); // container를 root 안에 표시하겠다.
</script>
</html><script type="text/babel">
const root = document.getElementById("root");
let counter = 0;
function countUp() {
counter = counter + 1;
Render();
}
function Render(){
ReactDOM.render(<Container />, root); // 여기에다가 리렌더링 하는 코드를 추가하면 된다!
}
const Container = () => ( // 얘는 그저 함수일 뿐
<div>
<h3>Total clicks: {counter}</h3>
<button onClick={countUp}>Click me</button>
</div>
);
// 별도의 이벤트리스너 없이 함수를 element에 넣어서 동작 가능
// 하지만 바로 반영되지 않음 -> UI 업데이트는 밑에서 한 번만 실행되기 때문 -> line 19
// vanillaJS에서는 div->h3->count가 전부 업데이트 되지만 React에서는 count만 업데이트 된다.
Render(); // render하는 함수 호출
</script>
</html>
<script type="text/babel">
const root = document.getElementById("root");
function App(){ // 얘는 그저 함수일 뿐
// const data = React.useState(101);
// console.log(data); // [undefined, f] 리스트 출력 -> 순서대로 counter와 countUp의 역할을 한다.
// const counter = data[0];
// const modifier = data[1];
// 이렇게 해도 되지만 좀 더 나은 방식이 존재함
const [counter, modifier] = React.useState(0);
return (
<div>
<h3>Total clicks: {counter}</h3>
<button>Click me</button>
</div>
);
};
ReactDOM.render(<App />, root);
</script>
<script type="text/babel">
const root = document.getElementById("root");
function App(){ // 얘는 그저 함수일 뿐
const [counter, setCounter] = React.useState(0);
const onClick = () => {
//counter += 1;
//console.log(counter);
// state를 사용하긴 했지만 여전히 리렌더링은 일어나지 않음 -> 변수를 직접 사용하지 말고 modifier를 써보자
setCounter(counter+1); // 여기서 counter = 15121; ReactDOM.render()가 전부 일어남
};
return (
<div>
<h3>Total clicks: {counter}</h3>
<button onClick = {onClick}>Click me</button>
</div>
);
};
ReactDOM.render(<App />, root);
</script>
⇒ 결국 render 함수를 일일이 체크해서 작성할 필요 없이 매번 해줌
<script type="text/babel">
function App() { // 얘는 그저 함수일 뿐
const [minutes, setMinutes] = React.useState();
const onChange = (event) => {
setMinutes(event.target.value);
console.log(event);
};
const reset = () =>{
setMinutes(0);
}
return (
<div>
<div>
<h3>Super Converter</h3>
<label htmlFor="minutes" >Minutes</label>
<input
value={minutes}
id="minutes"
placeholder="Minutes"
type="Number"
onChange={onChange}
/>
</div>
<div>
<label htmlFor="hours" >Hours</label>
<input value={minutes/60} id="hours" placeholder="Hours" type="Number" disabled />
</div>
<button className="reset" onClick={reset}>Reset</button>
</div>
);
};
const root = document.getElementById("root");
ReactDOM.render(<App />, root);
</script>
<script type="text/babel">
function App() { // 얘는 그저 함수일 뿐
const [amount, setAmount] = React.useState();
const [flipped, setFlipped] = React.useState(false);
const onChange = (event) => {
setAmount(event.target.value);
console.log(event);
};
const reset = () => {
setAmount(0);
}
const onFlip = () => {
reset();
setFlipped((current) => !current);
}
return (
<div>
<div>
<h3>Super Converter</h3>
<label htmlFor="minutes" >Minutes</label>
<input
value={flipped ? amount*60 : amount}
id="minutes"
placeholder="Minutes"
type="Number"
onChange={onChange}
disabled={flipped}
/>
</div>
<div>
<label htmlFor="hours" >Hours</label>
<input
value={flipped ? amount : Math.round(amount / 60)}
id="hours"
placeholder="Hours"
type="Number"
disabled={!flipped}
onChange={onChange}
/>
</div>
<button className="reset" onClick={reset}>Reset</button>
<button onClick={onFlip}>Flip</button>
</div>
);
};
const root = document.getElementById("root");
ReactDOM.render(<App />, root);
</script>
script type="text/babel">
function MinutesToHours() { // 얘는 그저 함수일 뿐
const [amount, setAmount] = React.useState();
const [flipped, setFlipped] = React.useState(false);
const onChange = (event) => {
setAmount(event.target.value);
console.log(event);
};
const reset = () => {
setAmount(0);
}
const onFlip = () => {
reset();
setFlipped((current) => !current);
}
return (
<div>
<div>
<h3>Minutes To Hours</h3>
<label htmlFor="minutes" >Minutes</label>
<input
value={flipped ? amount * 60 : amount}
id="minutes"
placeholder="Minutes"
type="Number"
onChange={onChange}
disabled={flipped}
/>
</div>
<div>
<label htmlFor="hours" >Hours</label>
<input
value={flipped ? amount : Math.round(amount / 60)}
id="hours"
placeholder="Hours"
type="Number"
disabled={!flipped}
onChange={onChange}
/>
</div>
<button className="reset" onClick={reset}>Reset</button>
<button onClick={onFlip}>Flip</button>
</div>
);
};
function KmToMiles() {
const [amount, setAmount] = React.useState();
const [flipped, setFlipped] = React.useState(false);
const onChange = (event) => {
setAmount(event.target.value);
console.log(event);
};
const reset = () => {
setAmount(0);
}
const onFlip = () => {
reset();
setFlipped((current) => !current);
}
return (
<div>
<div>
<h3>Kilometers To Miles</h3>
<label htmlFor="kilometers" >Kilometers</label>
<input
value={flipped ? amount * 1.61 : amount}
id="kilometers"
placeholder="kilometers"
type="Number"
onChange={onChange}
disabled={flipped}
/>
</div>
<div>
<label htmlFor="miles" >Miles</label>
<input
value={flipped ? amount : Math.round(amount * 0.621)}
id="miles"
placeholder="miles"
type="Number"
disabled={!flipped}
onChange={onChange}
/>
</div>
<button className="reset" onClick={reset}>Reset</button>
<button onClick={onFlip}>Flip</button>
</div>
);
}
function App() {
const [index, setIndex] = React.useState("xx");
const onSelect = (event) => {
setIndex(event.target.value);
}
return (
<div>
<h1>Super Converter</h1>
<select value={index} onChange={onSelect}>
<option value="xx">Select your units</option>
<option value="0">Minutes & Hours</option>
<option value="1">KM & Miles</option>
</select>
<hr />
{index === "xx" ? "Please select your unit" : null}
{index === "0" ? <MinutesToHours /> : null}
{index === "1" ? <KmToMiles /> : null}
</div>
); // 기능들을 component화, 분할 정복, 유저 선택에 따라 다른 기능을 보여주고 싶음 -> App에서 state
};
const root = document.getElementById("root");
ReactDOM.render(<App />, root);
</script>
<script type="text/babel">
//props 하나로 모든 인자 핸들링, 객체임
function Btn({banana, big}) {
return <button style={{
backgroundColor: "tomato",
color: "white",
padding: "10px 20px",
borderRadius: 10,
fontSize: big ? 18 : 14,
}}
>
{banana}
</button>
}
// props.banana로 사용해도 되지만 shortcut으로 {banana}로 사용 가능
function ConfirmBtn() {
return <button>Confirm</button>
}
// 1.component는 JSX를 반환하는 단지 함수일 뿐임
// 2.두 버튼은 텍스트만 다른데 스타일을 계속 지정하는건 귀찮음 -> 텍스트만 바꾸자
// 3. ConfirmBtn 삭제, SaveBtn -> Btn
function App() {
return (
<div>
<Btn banana ="SaveChange" big={true} />
<Btn banana ="Confirm" />
</div>
); // 인자를 넘기는 것과 동일하게 동작, 인자명은 마음대로
};
const root = document.getElementById("root");
ReactDOM.render(<App />, root);
</script>
<script type="text/babel">
function Btn({ banana, changeValue }) {
console.log(banana, "was created");
// 앞의 버튼만 리렌더링되지 않고 두 버튼 다 리렌더링된다.
// 이걸 방지하려면? React memo, memorize
return (
<button
onClick={changeValue}
// function을 인자로 받아와서 이벤트 리스너에 직접 넣어줘야 함
style={{
backgroundColor: "tomato",
color: "white",
padding: "10px 20px",
borderRadius: 10,
}}
>
{banana}
</button>
)
}
function ConfirmBtn() {
return <button>Confirm</button>
}
const MemorizedBtn = React.memo(Btn); // 이걸 사용하자
function App() {
const [value, setValue] = React.useState("Save Changes");
const changeValue = () => {
setValue("Revert Changes");
}
return (
<div>
<MemorizedBtn banana={value} changeValue={changeValue} />
<MemorizedBtn banana="Confirm" />
</div>
); // <Btn banana = {value} onClick={changeValue}/> 같이 작성하는건 그저 인자지 절대 이벤트리스너가 아님
// 해당 컴포넌트 내부에 이벤트를 직접 작성해야 함
};
// 핵심은 부모 컴포넌트의 state가 변경되면 자식 컴포넌트는 모두 re-render됨, 일단 알아만두자
// 해당 컴포넌트의 props가 변경되어야만 변경된다.
const root = document.getElementById("root");
ReactDOM.render(<App />, root);
</script>
<script src="https://unpkg.com/react@17.0.2/umd/react.development.js"></script>
<script src="https://unpkg.com/react-dom@17.0.2/umd/react-dom.production.min.js"></script>
<script src="https://unpkg.com/prop-types@15.7.2/prop-types.js"></script>
<script src="https://unpkg.com/@babel/standalone/babel.min.js"></script>
<script type="text/babel">
//props 하나로 모든 인자 핸들링, 객체임
function Btn({ banana, fontSize }) {
console.log(banana, "was created");
return (
<button
style={{
backgroundColor: "tomato",
color: "white",
padding: "10px 20px",
borderRadius: 10,
fontSize: fontSize,
}}
>
{banana}
</button>
)
}
const MemorizedBtn = React.memo(Btn); // 이걸 사용하자
Btn.propTypes = {
banana: PropTypes.string.isRequired,
fontSize: PropTypes.number,
};
// 여기서 타입 검사 가능, type을 지정하면 해당 타입이 아닐 경우 오류 발생, isRequired를 지정하면 입력 안할시 오류 발생
function App() {
const [value, setValue] = React.useState("Save Changes");
const changeValue = () => {
setValue("Revert Changes");
}
return (
<div>
<Btn banana={value} fontSize={20} />
<Btn banana="Confirm" />
</div>
); // 이렇게 fontSize에 문자열을 넣어도 코드상 에러는 없음, React는 무슨 타입을 받을지 모른다
// 그치만 propTypes를 지정하여 타입 검사 가능
};
const root = document.getElementById("root");
ReactDOM.render(<App />, root);
</script>
npx create-react-app (project name)npm startimport { useState, useEffect } from "react";
import styles from "./App.module.css";
// useEffect가 개발되어 있음 -> 첫 인자로는 한 번만 실행하고 싶은 코드, 두 번째 인자는 좀 나중에 설명
function App() {
const [counter, setCounter] = useState(0);
const [keyword, setKeyword] = useState("");
// CRA를 써서 일일이 React.~ 쓸 필요 없음
const onClick = () => setCounter((prev) => prev + 1);
const onChange = (event) => {
setKeyword(event.target.value);
};
// 특히나 input에서 변화할때마다 render하면 문자 하나 입력할 때마다 출력된다.
console.log("i run all the time");
useEffect(() => {
console.log("i run only once.");
}, []);
// useEffect안에 넣어 놓은 코드는 첫 실행 시 한번만 출력된다.
// console.log("SEARCH FOR", keyword);
// 이것도 다른 state 변화 시 계속 출력 됨 -> 우리가 원하는건 키워드를 입력할 때만 검색하는 것
useEffect(() => {
if (keyword != "" && keyword.length > 5) {
console.log("SEARCH FOR", keyword);
}
}, [keyword]); // 이렇게 하면 keyword가 변할 때만 실행 가능하다.
useEffect(() => {
console.log("i run when counter changes");
}, [counter]); // 이렇게 하면 counter가 변할 때만 실행 가능하다.
useEffect(() => {
console.log("i run when keyword and counter changes");
}, [keyword]); // 이렇게 하면 둘 다 변할 때 모두 실행된다..
return (
<div>
<input
value={keyword}
onChange={onChange}
type="text"
placeholder="Search here..."
/>
<h1>{counter}</h1>
<button onClick={onClick}>click me</button>
</div>
);
}
// 첫 render시에만 코드가 실행되도록 하길 원할 수 있음 ex) API 호출
export default App;
import { useState, useEffect } from "react";
import styles from "./App.module.css";
function Hello() {
function byFn(){
console.log("Bye :(");
}
function hiFn(){
console.log("Created :)")
return byFn;
}
useEffect(hiFn,[]);
return <h1>Hello</h1>;
}
function App() {
const [showing, setShowing] = useState(false);
const onClick = () => {
setShowing((prev) => !prev);
};
return (
<div>
{showing ? <Hello /> : null}
<button onClick={onClick}>{showing ? "Hide" : "Show"}</button>
</div>
);
// 버튼을 누르면 Hello가 생기고 다시 누르면 destroy된다.
// 따라서 Created는 새로 생성 될 때마다 실행된다.
// 파괴할 때도 실행하고 싶다면?
// useEffect에서 return으로 넣어두자
}
export default App;