6주차에는 React가 어떤 것인지 체험해보는 시간이었다. 이 과정을 수강하기 전에 구글링만을 가지고 어거지로 만들었던 페이지들이 생각나면서 약간 부끄럽고, 다음엔 조금 더 낫도록, 또한 왜 에러가 났었는지 좀 더 잘 알 수 있지 않을까 하는 생각이 들었다.
문서를 논리 트리
로 표현한다.
ㄴ 특정 라이브러리나 프레임워크를 사용하지 않은 그 자체의 자바스크립트
웹에서 사용되는 다양한 컨텐츠(리소스)를 저장하여 제공하는 시스템 - unpkg
React.createElement(
type,
[props],
[...Children]
)
ReactDOM.render(element, container[, callback])
// 주입할 element, root로 생각할 cotainer
createElement()로 매번 요소를 만드는 것 불편하다.
문자도 HTML도 아닌 JavaScript의 확장문법
const element = <h1>Hello, world!</h1>;
-> JavaScript Complier
컴파일러 : 언어 해석기, 특정 언어를 다른 프로그래밍 언어로 옮기는 프로그램
// 바벨 불러오기
<script src="https://unpkg.com/@babel/standalone/babel.min.js">
</script>
// 스크립트 읽게 할 코드들 적기
<script type="text/babel">
const rootElement = document.getElementById("root");
const element = <h1 className="title">Hello, world!</h1>
</script>
// 바벨 불러오기
<script type="text/babel">
const rootElement = document.getElementById("root");
const text = "Hello, world";
const titleClassName = "title1234";
const props = {className: titleClassName, childeren: text}
const customH1 = <h1 {... props}/>;
// 위아래는 동일하다. // sprend 연산자 ...
// <h1 className={props.className} children={props.children} />
const element = customH1;
ReactDOM.render(element, rootElement);
</script>
<div id="root">
<h1>Hi</h1>
<h3>Bye</h3>
<h5>Children</h5>
</div>
<script src="https://unpkg.com/@babel/standalone/babel.min.js">
</script>
<script type="text/babel">
const rootElement = document.getElementById("root");
const element = (
<div
className="box"
children={[
React.createElement("h1", null, "Hi"),
React.createElement("h3", null, "Bye"),
React.createElement("h6", null, "Children")
]}
/>
);
ReactDOM.render(element, rootElement);
</script>
// 해석해보면 위의 html 형태는 div아래 바로 요소들이 있는데
// react표현은 chirdren안에 요소를 넣어야 하므로
// div className="box" 를 생성해 감싸고 그 안에 요소로 넣어야 한다
// 즉, 모양이 같지 않다.
// React.Fragment를 쓰면 동일하게 표현 가능
<script src="https://unpkg.com/@babel/standalone/babel.min.js">
</script>
<script type="text/babel">
const rootElement = document.getElementById("root");
const element = (
<React.Fragment
children={[
React.createElement("h1", null, "Hi"),
React.createElement("h3", null, "Bye"),
React.createElement("h6", null, "Children")
]}
/>
);
ReactDOM.render(element, rootElement);
</script>
// React.Fragment는 type요소 생성 없이 감싸기만 해서
// children 요소 생성 가능하다.
<script src="https://unpkg.com/@babel/standalone/babel.min.js">
</script>
<script type="text/babel">
const rootElement = document.getElementById("root");
const element = (
<React.Fragment
children={[<h1>Hi</h1>, <h3>Bye</h3>, <h5>Children</h5>]}
/>
);
ReactDOM.render(element, rootElement);
</script>
// 이렇게 까지 정리가 가능하다.
const element = (
<React.Fragment>
<h1>Hi</h1>
<h3>Bye</h3>
<h5>Children</h5>
</React.Fragment>
);
// 거의 html 모양과 유사해졌지만, jsx 변수표현로 만든것임 확인
const element = (
<>
<h1>Hi</h1>
<h3>Bye</h3>
<h5>Children</h5>
</>
);
// 빈태그는 < React.Fragment > 와 동일하다
// 함수로 만들어 놓고 반복시켜 요소 찍어내기 가능
<script src="https://unpkg.com/@babel/standalone/babel.min.js">
</script>
<script type="text/babel">
const rootElement = document.getElementById("root");
const paint = (title, description) => (
<>
<h1>{title}</h1>
<h3>{description}</h3>
</>
);
const element = (
<>
{paint("Good","good")}
{paint("Bad","bad")}
{paint("SoSo","soso")}
</>
);
ReactDOM.render(element, rootElement);
</script>
// 함수로 만들어 놓고 반복시켜 요소 찍어내기 가능
<script src="https://unpkg.com/@babel/standalone/babel.min.js">
</script>
<script type="text/babel">
const rootElement = document.getElementById("root");
// 이렇게 표현하고 싶으면 꼭 첫 글자를 대문자로 표현해줘야한다.
const Paint = ({ title, description }) => {
return (
<>
<h1>{title}</h1>
<h3>{description}</h3>
</>
);
};
// { return } 생략 가능함 기억하자.
const element = (
<>
<Paint title="Good" description="good" />
<Paint title="Bad" description="bad" />
<Paint title="SoSo" description="soso" />
</>
);
ReactDOM.render(element, rootElement);
</script>
// 동일하게 작동한다.
Children
제한 없다. 갯수 무제한
// 함수 매개변수로 첫글자 대문자로 넣으면 h1으로 출력,
// 소문자이면 h3로 출력되게 만들어 보겠다.
<script src="https://unpkg.com/@babel/standalone/babel.min.js">
</script>
<script type="text/babel">
const rootElement = document.getElementById("root");
const Text = ({ text }) => {
if (text.charAt(0) === text.charAt(0).toUpperCase()) {
return <h1>{text}</h1>
} else {
return <h3>{text}</h3>
}
};
const element = (
<>
<Text text="Hi" />
<Text text="hi" />
</>
);
ReactDOM.render(element, rootElement);
</script>
<script src="https://unpkg.com/@babel/standalone/babel.min.js">
</script>
<script type="text/babel">
const rootElement = document.getElementById("root");
const Number = ({ number }) => {
return number % 2 === 0 ? <h1>{number}</h1> : <h3>{number}</h3>;
}
const element = (
<>
<Number number={1} />
<Number number={2} />
<Number number={3} />
<Number number={4} />
</>
);
ReactDOM.render(element, rootElement);
</script>
<script src="https://unpkg.com/@babel/standalone/babel.min.js">
</script>
<script type="text/babel">
const rootElement = document.getElementById("root");
const Number = ({ number, selected }) => {
return selected ? <h1>{number}</h1> : <h3>{number}</h3>;
}
const element = (
<>
<Number number={1} />
<Number number={2} selected={true} />
<Number number={3} />
<Number number={4} />
</>
);
<script src="https://unpkg.com/@babel/standalone/babel.min.js">
</script>
<script type="text/babel">
const rootElement = document.getElementById("root");
const Number = ({ number, selected }) => {
return selected ? <h1>{number}</h1> : <h3>{number}</h3>;
}
const element = (
<>
{[1,2,3,4,5,6,7,8,9,10].map((number) => (
<Number number={number} selected={number === 3} />
))}
</>
);
ReactDOM.render(element, rootElement);
</script>
<!DOCTYPE html>
<html lang="en">
<body>
<button id="button" onclick="document.getElementById('demo').innerHTML=Date()">The time is?</button>
// 인라인으로 이벤트 넣기
<p id="demo"></p>
<script>
const button = document.getElementById("button");
button.addEventListener("mouseout", () => alert("bye"));
button.addEventListener("click", () => alert("press"));
</script>
</body>
</html>
카멜케이스
로 표현<!DOCTYPE html>
<html lang="en">
<body>
<div id="root"></div>
<script src="https://unpkg.com/react@17/umd/react.development.js"></script>
<script src="https://unpkg.com/react-dom@17/umd/react-dom.development.js"></script>
<script src="https://unpkg.com/@babel/standalone/babel.min.js"></script>
<script type="text/babel">
const rootElement = document.getElementById("root");
const handleClick = () => alert("pressed");
const handleMouseOut = () => alert("bye");
const element = (
<button onClick={handleClick} onMouseOut={handleMouseOut}>
Press
</button>
);
ReactDOM.render(element, rootElement);
</script>
</body>
</html>
<!DOCTYPE html>
<html lang="en">
<body>
<div id="root"></div>
<script src="https://unpkg.com/react@17/umd/react.development.js"></script>
<script src="https://unpkg.com/react-dom@17/umd/react-dom.development.js"></script>
<script src="https://unpkg.com/@babel/standalone/babel.min.js"></script>
<script type="text/babel">
const rootElement = document.getElementById("root");
const state = { keyword: "", typing: false, result: "" };
const App = () => {
function handleChange(event) {
setState({ typing: true, keyword: event.target.value });
}
function handleClick() {
setState({
typing: false,
result: "we find results of ${state.keyword}"
});
}
return (
<>
<input onChange={handleChange} />
<button onClick={handleClick}>search</button>
<p>
{state.typing ? `Looking for ${state.keyword}...` : state.result}
</p>
</>
);
};
function setState(newState) {
Object.assign(state, newState);
render();
}
function rander() {
ReactDOM.render(<App />, rootElement);
}
</script>
</body>
</html>
앨리먼트의 집합
<!DOCTYPE html>
<html lang="en">
<body>
<div id="root"></div>
<script src="https://unpkg.com/react@17/umd/react.development.js"></script>
<script src="https://unpkg.com/react-dom@17/umd/react-dom.development.js"></script>
<script src="https://unpkg.com/@babel/standalone/babel.min.js"></script>
<script type="text/babel">
const rootElement = document.getElementById("root");
const App = () => {
const [keyword, setKeyword] = React.useState("");
const [result, setResult] = React.useState();
const [typing, setTyping] = React.useState(false);
function handleChange(event) {
setKeyword(event.target.value);
setTyping(true);
}
function handleClick() {
setTyping(false);
setResult(`We find results of ${keyword}`);
}
return (
<>
<input onChange={handleChange} />
<button onClick={handleClick}>search</button>
<p>{typing ? `Looking for ${keyword}...`: result}</p>
</>
);
};
ReactDOM.render(<App />, rootElement);
</script>
</body>
</html>
부수효과
<!DOCTYPE html>
<html lang="en">
<body>
<div id="root"></div>
<script src="https://unpkg.com/react@17/umd/react.development.js"></script>
<script src="https://unpkg.com/react-dom@17/umd/react-dom.development.js"></script>
<script src="https://unpkg.com/@babel/standalone/babel.min.js"></script>
<script type="text/babel">
const rootElement = document.getElementById("root");
const App = () => {
const [keyword, setKeyword] = React.useState(() => {
return window.localStorage.getItem("keyword") || "";
);
const [result, setResult] = React.useState("");
const [typing, setTyping] = React.useState(false);
React.useEffect(() => {
window.localStorage.setItem("keyword", keyword);
}, [keyword, typing]); //의존성 배열 (어떤 값이 변할때 효과가 일어나게 하고 싶은가?)
function handleChange(event) {
window.localStorage.setItem("keyword", event.target.value);
setKeyword(event.target.value);
setTyping(true);
}
function handleClick() {
setTyping(false);
setResult(`We find results of ${keyword}`);
}
return (
<>
<input onChange={handleChange} value={keyword} />
<button onClick={handleClick}>search</button>
<p>{typing ? `Looking for ${keyword}...`: result}</p>
</>
);
};
ReactDOM.render(<App />, rootElement);
</script>
</body>
</html>
<!DOCTYPE html>
<html lang="en">
<body>
<div id="root"></div>
<script src="https://unpkg.com/react@17/umd/react.development.js"></script>
<script src="https://unpkg.com/react-dom@17/umd/react-dom.development.js"></script>
<script src="https://unpkg.com/@babel/standalone/babel.min.js"></script>
<script type="text/babel">
const rootElement = document.getElementById("root");
function useLocalStorage(itemName, value = "") {
const [state, setState] = React.useState(() => {
return window.localStorage.getItem(itemName) || value;
);
React.useEffect(() => {
window.localStorage.setItem(itemName, state);
}, [state]);
return [state, setState]; // useState 같은 훅과 동일한 형태로 만들고 싶은 것
}
const App = () => {
const [keyword, setKeyword] = useLocalStorage("keyword");
const [result, setResult] = useLocalStorage("result");
const [typing, setTyping] = useLocalStorage("typing", false);
function handleChange(event) {
setKeyword(event.target.value);
setTyping(true);
}
function handleClick() {
setTyping(false);
setResult(`We find results of ${keyword}`);
}
return (
<>
<input onChange={handleChange} value={keyword} />
<button onClick={handleClick}>search</button>
<p>{typing ? `Looking for ${keyword}...`: result}</p>
</>
);
};
ReactDOM.render(<App />, rootElement);
</script>
</body>
</html>
<!DOCTYPE html>
<html lang="en">
<body>
<div id="root"></div>
<script src="https://unpkg.com/react@17/umd/react.development.js"></script>
<script src="https://unpkg.com/react-dom@17/umd/react-dom.development.js"></script>
<script src="https://unpkg.com/@babel/standalone/babel.min.js"></script>
<script type="text/babel">
const rootElement = document.getElementById("root");
const Child = () => {
console.log(" Child render start");
const [text, setText] = React.useState(() => {
console.log(" Child useState");
return "";
});
React.useEffect(() => {
console.log(" Child useEffect, no deps");
return () => {
console.log(" Child useEffect [Cleanup], no deps");
};
});
React.useEffect(() => {
console.log(" Child useEffect, empty deps");
return () => {
console.log(" Child useEffect [Cleanup], empty deps");
};
}, []);
React.useEffect(() => {
console.log(" Child useEffect, [text]");
return () => {
console.log(" Child useEffect [Cleanup], [text]");
};
}, [text]);
function handleChange(event) {
setText(event.target.value);
}
const element = (
<>
<input onChange={handleChange} />
<p>{text}</p>
</>
);
console.log(" Child render end");
return element;
};
const App = () => {
console.log("APP render start");
const [show, setShow] = React.useState(() => {
console.log("APP useState");
return false;
});
React.useEffect(() => {
console.log("APP useEffect, no deps");
return () => {
console.log("APP useEffect [Cleanup], no deps");
};
});
React.useEffect(() => {
console.log("APP useEffect, empty deps");
return () => {
console.log("APP useEffect [Cleanup], empty deps");
};
}, []);
React.useEffect(() => {
console.log("APP useEffect, [show]");
return () => {
console.log("APP useEffect [Cleanup], [show]");
};
}, [show]);
function handleClick() {
setShow((prev) => !prev);
}
console.log("APP render end");
return (
<>
<button onClick={handleClick}>Search</button>
{show ? <Child /> : null}
</>
);
};
ReactDOM.render(<App />, rootElement);
</script>
</body>
</html>
<body>
<div id="root"></div>
<script src="https://unpkg.com/react@16.12.0/umd/react.development.js"></script>
<script src="https://unpkg.com/react-dom@16.12.0/umd/react-dom.development.js"></script>
<script src="https://unpkg.com/@babel/standalone@7.8.3/babel.js"></script>
<style>
.button {
background-color: #4caf50; /* Green */
border: none;
color: white;
padding: 15px 32px;
text-align: center;
text-decoration: none;
display: inline-block;
font-size: 16px;
margin: 4px 2px;
cursor: pointer;
}
.blue {
background-color: #008cba;
} /* Blue */
.red {
background-color: #f44336;
} /* Red */
.gray {
background-color: #e7e7e7;
color: black;
}
.black {
background-color: #555555;
}
</style>
<script type="text/babel">
function Button({ className = "", color, style, ...rest }) {
return (
<button
className={`button ${className}`}
style={{ backgroundColor: color, borderRadius: 8, ...style }}
{...rest}
/>
);
}
const element = (
<>
<Button style={{ borderRadius: "50%" }}>Green</Button>
<Button color="blue">Blue</Button>
<Button color="red">Red</Button>
<Button color="gray">Gray</Button>
<Button color="black">Black</Button>
</>
);
ReactDOM.render(element, document.getElementById("root"));
</script>
</body>
</html>
<!DOCTYPE html>
<html lang="en">
<body>
<div id="root"></div>
<script src="https://unpkg.com/react@17/umd/react.development.js"></script>
<script src="https://unpkg.com/react-dom@17/umd/react-dom.development.js"></script>
<script src="https://unpkg.com/@babel/standalone/babel.min.js"></script>
<script type="text/babel">
const rootElement = document.getElementById("root");
const App = () => {
React.useEffect({
document.getElementById("input").focus();
},[]);
return (
<>
<input id="input" />
</>;
);
};
ReactDOM.render(<App />, rootElement);
</script>
</body>
</html>
<!DOCTYPE html>
<html lang="en">
<body>
<div id="root"></div>
<script src="https://unpkg.com/react@17/umd/react.development.js"></script>
<script src="https://unpkg.com/react-dom@17/umd/react-dom.development.js"></script>
<script src="https://unpkg.com/@babel/standalone/babel.min.js"></script>
<script type="text/babel">
const rootElement = document.getElementById("root");
const App = () => {
const inputRef = React.useRef();
React.useEffect(() => {
inputRef.current.focus(); // useRef를 이용할때는 current라는 것을 쓰고 후에 메서드 줄 수 있다.
},[]);
return (
<>
<input ref={inputRef} />
</>;
);
};
ReactDOM.render(<App />, rootElement);
</script>
</body>
</html>
<!DOCTYPE html>
<html lang="en">
<body>
<div id="root"></div>
<script src="https://unpkg.com/react@17/umd/react.development.js"></script>
<script src="https://unpkg.com/react-dom@17/umd/react-dom.development.js"></script>
<script src="https://unpkg.com/@babel/standalone/babel.min.js"></script>
<script type="text/babel">
const rootElement = document.getElementById("root");
const App = () => {
const inputRef = React.useRef();
const divRef = React.useRef();
React.useEffect(() => {
inputRef.current.focus();
setTimeout(() => {
divRef.current.style.backgroundColor = "pink";
},1000);
},[]);
return (
<>
<input ref={inputRef} />
<div
ref={divRef}
style={{ height:100, width: 300, backgroundColor: "brown" }}
/>
</>;
);
};
ReactDOM.render(<App />, rootElement);
</script>
</body>
</html>
document.getElementById 류를 사용하지 않고.
useRef라는 별도의 방법
을 제공할까?
label
, input
, submit
<!DOCTYPE html>
<html lang="en">
<body>
<div id="root"></div>
<script src="https://unpkg.com/react@17/umd/react.development.js"></script>
<script src="https://unpkg.com/react-dom@17/umd/react-dom.development.js"></script>
<script src="https://unpkg.com/@babel/standalone/babel.min.js"></script>
<script type="text/babel">
const rootElement = document.getElementById("root");
const App = () => {
const handleSubmit = {event} => {
event.preventDefault(); // 디폴트 동작 하지 말아라 <- 새로고침처럼 깜빡이는거 안하게 됨
console.dir(event.target); // 콘솔창에 원하는 값 전체구조를 확인하게 해준다.
alert(
`FirstName : ${event.target[0].value}, LastName : ${event.target[1].value}`
); // 결국 이걸로도 가능했으나 위치 순서 뒤바뀔 것 같고 불안한 상태.
----------------------------------------------------------------------------------
const handleSubmit = {event} => {
event.preventDefault();
console.dir(event.target.elements); // 이안에도 FN, LN 있는 것 확인함. 써보자
alert(`FirstName : ${event.target.elements.fname.value},
LastName : ${event.target.elements.lname.value}`
); // 잘 작동하며, 구조에서 키로 찍혀있는 부분 가져다 사용하는 것 알아둘 것!
};
return (
<form onSubmit={handleSubmit}>
<label htmlFor="fname">First name:</label>
<br />
<input type="text" id="fname" name="fname" defaultValue="John" />
<br />
<label htmlFor="lname">Last name:</label>
<br />
<input type="text" id="lname" name="lname" defaultValue="Doe" />
<br />
<br />
<input type="submit" value="Submit" />
</form>
);
};
ReactDOM.render(<App />, rootElement);
</script>
</body>
</html>
<!DOCTYPE html>
<html lang="en">
<body>
<div id="root"></div>
<script src="https://unpkg.com/react@17/umd/react.development.js"></script>
<script src="https://unpkg.com/react-dom@17/umd/react-dom.development.js"></script>
<script src="https://unpkg.com/@babel/standalone/babel.min.js"></script>
<script type="text/babel">
const rootElement = document.getElementById("root");
const App = () => {
const handleSubmit = {event} => {
event.preventDefault(); // 디폴트 동작 하지 말아라 <- 새로고침처럼 깜빡이는거 안하게 됨
console.dir(event.target); // 콘솔창에 원하는 값 전체구조를 확인하게 해준다.
alert(
`FirstName : ${event.target[0].value}, LastName : ${event.target[1].value}`
); // 결국 이걸로도 가능했으나 위치 순서 뒤바뀔 것 같고 불안한 상태.
----------------------------------------------------------------------------------
const handleSubmit = {event} => {
event.preventDefault();
console.dir(event.target.elements);
alert(`FirstName : ${event.target.elements.fname.value},
Choosed Car : ${event.target.elements.cars.value}`
);
};
return (
<form onSubmit={handleSubmit}>
<label htmlFor="fname">First name:</label>
<br />
<input type="text" id="fname" name="fname" defaultValue="John" />
<br />
<label htmlFor="cars">Choose a car:</label>
<select id="cars" name="cars">
<option value="volvo">Volvo</option>
<option value="saab">Saab</option>
<option value="fiat">Fiat</option>
<option value="audi">Audi</option>
</select>
<br />
<br />
<input type="submit" value="Submit" />
</form>
);
};
ReactDOM.render(<App />, rootElement);
</script>
</body>
</html>
<!DOCTYPE html>
<html lang="en">
<body>
<div id="root"></div>
<script src="https://unpkg.com/react@17/umd/react.development.js"></script>
<script src="https://unpkg.com/react-dom@17/umd/react-dom.development.js"></script>
<script src="https://unpkg.com/@babel/standalone/babel.min.js"></script>
<script type="text/babel">
const rootElement = document.getElementById("root");
const App = () => {
const [message, setMessage] = React.useState("");
const [phoneNumber, setPhoneNumber] = React.useState("");
const handleSubmit = (event) => {
event.preventDefault();
alert(phoneNumber);
};
const handleChange = (event) => {
if (event.target.value.startsWith(0)) {
setMessage("phone Number is valid");
setPhoneNumber(event.target.value);
} else if (event.tartget.value.length === 0) {
setPhoneNumber("");
setMessage("");
} else {
setMessage("phone Number should starts with 0");
}
};
return (
<form onSubmit={handleSubmit}>
<label htmlFor="phone">Phone Number: </label>
<br />
<input
id="phone"
name="phone"
onChange={handleChange}
value={phoneNumber}
/>
<p>{message}</p>
<br />
<br />
<button
type="submit"
disabled={
phoneNumber.length === 0 || message !== "Phone Number is valid"
}
>
Submit
</button>
<p>{phoneNumber}</p>
</form>
);
};
ReactDOM.render(<App />, rootElement);
</script>
</body>
</html>
try{
[에러가 날수도 있는 코드]
} catch (error) {
[에러가 났을 때 어떻게 처리할지]
}
<!DOCTYPE html>
<html lang="en">
<body>
<div id="root"></div>
<script src="https://unpkg.com/react@17/umd/react.development.js"></script>
<script src="https://unpkg.com/react-dom@17/umd/react-dom.development.js"></script>
<script src="https://unpkg.com/@babel/standalone/babel.min.js"></script>
<script type="text/babel">
const rootElement = document.getElementById("root");
class ErrorBoundary extends React.Component {
state = { error: null };
static getDerivedStateFromError(error) {
return { error };
}
render() {
const { error } = this.state;
if (error) {
return <this.props.fallback error={error} />;
}
return this.props.children;
}
}
const Child = () => {
throw new Error("Something Wrong....");
return <p>Child...</p>;
};
const Fallback = ({ error }) => {
alert(error.message);
return <p>There is some ERROR...</p>;
};
const App = () => {
return (
<>
<p>App</p>
<ErrorBoundary fallback={Fallback}>
<Child />
</ErrorBoundary>
</>
);
};
ReactDOM.render(<App />, rootElement);
</script>
</body>
</html>
Fallback
----> Error가 났을 때 보여줄 컴포넌트!!특정
하는 이름
<html lang="en">
<body>
<div id="root"></div>
<script src="https://unpkg.com/react@17/umd/react.development.js"></script>
<script src="https://unpkg.com/react-dom@17/umd/react-dom.development.js"></script>
<script src="https://unpkg.com/@babel/standalone/babel.min.js"></script>
<script type="text/babel">
const rootElement = document.getElementById("root");
const todos = [
{ id: 1, value: "Wash dishes" },
{ id: 2, value: "Clean the bed" },
{ id: 3, value: "Running" },
{ id: 4, value: "Learning" }
];
const App = () => {
const[items, setItems] = React.useState(todos);
const handleDoneClick = (todo) => {
setItems((items) => items.filter((item) => item !== todo));
};
const handleRestoreClick = () => {
setItems((items) => [
...items,
todos.find((item) => !items.includes(item))
]);
};
return (
<>
{items.maps((todo) => (
<div key={todo.id}>
<span>{todo.value}</span>
<button onClick={() => handleDoneClick(todo)}>Done</button>
</div>
))}
<button onClick={handleRestoreClick}>Restore</button>
</>
);
};
ReactDOM.render(<App />, rootElement);
</script>
</body>
</html>
Detail
<html lang="en">
<body>
<div id="root"></div>
<script src="https://unpkg.com/react@17/umd/react.development.js"></script>
<script src="https://unpkg.com/react-dom@17/umd/react-dom.development.js"></script>
<script src="https://unpkg.com/@babel/standalone/babel.min.js"></script>
<script type="text/babel">
const rootElement = document.getElementById("root");
const todos = [
[
{ id: 1, value: "Wash dishes" },
{ id: 2, value: "Clean the bed" },
{ id: 3, value: "Running" },
{ id: 4, value: "Learning" }
],
[
{ id: 4, value: "Learning" },
{ id: 1, value: "Wash dishes" },
{ id: 2, value: "Clean the bed" },
{ id: 3, value: "Running" }
],
[
{ id: 3, value: "Running" },
{ id: 4, value: "Learning" },
{ id: 1, value: "Wash dishes" },
{ id: 2, value: "Clean the bed" }
],
[
{ id: 2, value: "Clean the bed" },
{ id: 4, value: "Learning" },
{ id: 3, value: "Running" },
{ id: 1, value: "Wash dishes" }
]
];
const App = () => {
const[items, setItems] = React.useState(todos[0]);
React.useEffect(() => {
const interval = setInterval(() => {
const random = Math.floor(Math.random() * 3);
setItems(todos[random]);
}, 1000);
return () => {
clearInterval(interval);
};
}, []);
const handleDoneClick = (todo) => {
setItems((items) => items.filter((item) => item !== todo));
};
const handleRestoreClick = () => {
setItems((items) => [
...items,
todos.find((item) => !items.includes(item))
]);
};
return (
<>
{items.maps((todo, index) => (
<div key={todo.id}>
<button onClick={() => handleDoneClick(todo)}>
{todo.value}
</button>
</div>
))}
<br />
<br />
<button onClick={handleRestoreClick}>Restore</button>
</>
);
};
ReactDOM.render(<App />, rootElement);
</script>
</body>
</html>
재조정(Reconciliation)
개념 더 체크해보기.
react문서에서 확인
<html lang="en">
<body>
<div id="root"></div>
<script src="https://unpkg.com/react@17/umd/react.development.js"></script>
<script src="https://unpkg.com/react-dom@17/umd/react-dom.development.js"></script>
<script src="https://unpkg.com/@babel/standalone/babel.min.js"></script>
<script type="text/babel">
const rootElement = document.getElementById("root");
const Id = () => {
const [id, setId] = React.useState("");
const handleIdChange = (event) => {
setId(event.target.value);
console.log(`length: ${event.target.value.length}`);
};
return (
<>
<label>ID: </label>
<input onChange={handleIdChange}/>
</>
);
};
const Password = () => {
const [password, setPassword] = React.useState("");
const handlePasswordChange = (event) => {
setPassword(event.target.value);
console.log(`length: ${event.target.value.length}`);
};
return (
<>
<label>PW: </label>
<input type="password"
onChange={handlePasswordChange} />
</>
);
};
const App = () => {
const handleLoginClick = () => {
alert(`id: ${id}, pw: ${password}`);
};
return (
<>
<Id />
<br />
<Password />
<button disabled={true}
onClick={handleLoginClick}>
LOGIN
</button>
</>
);
};
ReactDOM.render(<App />, rootElement);
</script>
</body>
</html>
부모쪽으로 끌어올려놔보자.
<html lang="en">
<body>
<div id="root"></div>
<script src="https://unpkg.com/react@17/umd/react.development.js"></script>
<script src="https://unpkg.com/react-dom@17/umd/react-dom.development.js"></script>
<script src="https://unpkg.com/@babel/standalone/babel.min.js"></script>
<script type="text/babel">
const rootElement = document.getElementById("root");
# App에서 전달해준 것을 받는 형태로 변경!
const Id = ( { handleIdChange } ) => {
# 있던 것들이 App으로!
return (
<>
<label>ID: </label>
<input onChange={handleIdChange}/>
</>
);
};
const Password = ( { handlePasswordChange } ) => {
return (
<>
<label>PW: </label>
<input type="password"
onChange={handlePasswordChange} />
</>
);
};
const App = () => {
const [id, setId] = React.useState("");
const [password, setPassword] = React.useState("");
const handleIdChange = (event) => {
setId(event.target.value);
console.log(`id length: ${event.target.value.length}`);
};
const handlePasswordChange = (event) => {
setPassword(event.target.value);
console.log(`password length: ${event.target.value.length}`);
};
const handleLoginClick = () => {
alert(`id: ${id}, pw: ${password}`);
};
return (
<>
<Id handleIdChange={handleIdChange} /> # 자식으로 전달
<br /> # 자식으로 전달
<Password handlePasswordChange={handlePasswordChange}/>
<button disabled={id.length ===0 || password.length === 0}
onClick={handleLoginClick}>
LOGIN
</button>
</>
);
};
ReactDOM.render(<App />, rootElement);
</script>
</body>
</html>
lifting up
<-> drilling
좀 더 찾아봐도 좋을 것.
Fetch API
: 네트워크 통신 도구<html lang="en">
<body>
<div id="root"></div>
<script src="https://unpkg.com/react@17/umd/react.development.js"></script>
<script src="https://unpkg.com/react-dom@17/umd/react-dom.development.js"></script>
<script src="https://unpkg.com/@babel/standalone/babel.min.js"></script>
<script type="text/babel">
const rootElement = document.getElementById("root");
const App = () => {
const [data, setData] = React.useState(null);
const [error, setError] = React.useState(null);
React.useEffect(() => {
fetch("http://exaple.api.url")
.then(function (response) {
return response.json();
})
.then(function (myJson) {
setData(myJson.data);
})
.catch((error) => { #.catch로 error 잡을 수 있다.
setError(error.message);
alert(error);
});
}, []);
if (error != null) {
return <p>There is a error!</p>;
}
if (data == null) {
return <p>Loading....</p>;
}
return (
<div>
<p>People</p>
{data.people.map((person) => (
<div>
<span>name: {person.name} </span>
<span>age: {person.age}</span>
</div>
))}
</div>
);
};
ReactDOM.render(<App />, rootElement);
</script>
</body>
</html>
로딩
/ 데이터
/ 에러
)출처 : fastcampus_React & Redux로 시작하는 웹 프로그래밍