<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Document</title>
</head>
<body>
<div id="root"></div>
</body>
<!-- react import -->
<!-- <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/react@17.0.2/umd/react.development.js"></script>
<script src="https://unpkg.com/react-dom@17.0.2/umd/react-dom.development.js"></script>
<!-- babel import(jsx ->react로 변환) -->
<script src="https://unpkg.com/@babel/standalone/babel.min.js"></script>
<!-- 바벨 사용시 type 입력해주어야 한다. -->
<script type="text/babel">
// 분할과 정복(divide&Conquer(분할정복))
// App이 부모 컴포넌트 이고 MinutesToHours, KmToMiles가 자식 컴포넌트이다
// 이제부터 우리가 할것은 부모 컴포넌트로 부터 자식컴포넌트로 데이터를 보낼것이다.
// 상황 가정 : 우리가 만들려는 app에 다양한 기능들이 있는 버튼들이 있다.(로그인, 프로필, 화면이동 등등)
// 그런데 보면 각 버튼들의 디자인이 동일한 것을 알수있다. --> 디자이너들이 디자인을 만들기 때문
// 이렇게 동일한 디자인의 버튼에 대해서 우리가 알고 싶은 것은 어떻게 리액트 컴포넌트를 재활용 할 수 있는 지를 알고싶은것
// component라고 하는 것은 JSX를 반환하는 함수 일뿐이다.
// component는 항상 첫글자 대문자로
// SaveBtn(), ConfrimBtn() ==> 함수형 컴포넌트
// 이렇게 되면 버튼마다 일일이 스타일 지정해주어야 한다.
// props1에서 계속
function SaveBtn() {
return (
<button
style={{
backgroundColor: 'brown',
color: 'White',
padding: '10px 20px',
border: 0,
borderRadius: 10,
}}
>
Save Changes
</button>
)
}
function ConfrimBtn() {
return (
<button
style={{
backgroundColor: 'brown',
color: 'White',
padding: '10px 20px',
border: 0,
borderRadius: 10,
}}
>
Confrim
</button>
)
}
function App() {
// component는 항상 첫글자 대문자로
return (
<div>
<h1>Your Profile</h1>
<SaveBtn />
<span> </span>
<ConfrimBtn />
</div>
)
}
const root = document.querySelector('#root')
ReactDOM.render(<App />, root) // 생성한 element를 root인 위치에 그려줌(ReactDOM.render())
</script>
</html>
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Document</title>
</head>
<body>
<div id="root"></div>
</body>
<!-- react import -->
<!-- <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/react@17.0.2/umd/react.development.js"></script>
<script src="https://unpkg.com/react-dom@17.0.2/umd/react-dom.development.js"></script>
<!-- babel import(jsx ->react로 변환) -->
<script src="https://unpkg.com/@babel/standalone/babel.min.js"></script>
<!-- 바벨 사용시 type 입력해주어야 한다. -->
<script type="text/babel">
// props.html에서 계속
// 따라서 버튼 컴포넌트를 만들어서 재활용할 수있다.
// 하나의 컴포넌트(객체와 비슷)에서 자식 컴포넌트 props에 따라서 다르게 출력하면 어떨까?
// 부모 컴포넌트에서 정의한 자식 컴포넌트의 props를 받기위해서는 아래와 같이 할수있다.
// props는 하나의 인자만 있다.
/*function Btn(props) {
console.log(props)
return (
<button
style={{
backgroundColor: 'brown',
color: 'White',
padding: '10px 20px',
border: 0,
borderRadius: 10,
}}
>
{props.text}
</button>
)
}
*/
// 위 방식 말고 바로 props.text를 받는 방법은 아래와 같다
// {text}를 넣어주면 props.text와 같다.
function Btn({ text, big, bName }) {
console.log({ text, big, bName })
const handleClick = (event) => {
BtnClick(event, bName)
}
return (
<button
style={{
backgroundColor: 'brown',
color: 'White',
padding: '10px 20px',
border: 0,
borderRadius: 10,
fontSize: big ? 18 : 10,
}}
onClick={handleClick}
>
{text}
</button>
)
}
function BtnClick(event, bName) {
console.log(event)
console.log(bName)
if (bName === 'sChange') {
return alert('변경완료되었습니다.')
}
if (bName === 'sConfirm') {
alert('확인되었습니다.')
}
}
function App() {
// component는 항상 첫글자 대문자로
// 부모컴포넌트에 있는 자식 컴포넌트의 properties를 자식 컴포넌트(함수)에 보내서 다르게 출력이 가능하다.
// 자식 props에 있는 것(html의 tag의 type과 같은거)은 마음대로 정의가능하다.(나는 text로 정의한것일 뿐이다.)
return (
<div>
<h1>Your Profile</h1>
<Btn text="Save Changes" bName="sChange" big={true} />
<span> </span>
<Btn text="Confirm" bName="sConfirm" big={false} />
</div>
)
}
const root = document.querySelector('#root')
ReactDOM.render(<App />, root) // 생성한 element를 root인 위치에 그려줌(ReactDOM.render())
</script>
</html>
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Document</title>
</head>
<body>
<div id="root"></div>
</body>
<!-- react import -->
<!-- <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/react@17.0.2/umd/react.development.js"></script>
<script src="https://unpkg.com/react-dom@17.0.2/umd/react-dom.development.js"></script>
<!-- babel import(jsx ->react로 변환) -->
<script src="https://unpkg.com/@babel/standalone/babel.min.js"></script>
<!-- 바벨 사용시 type 입력해주어야 한다. -->
<script type="text/babel">
// props.html에서 계속
// 따라서 버튼 컴포넌트를 만들어서 재활용할 수있다.
// 하나의 컴포넌트(객체와 비슷)에서 자식 컴포넌트 props에 따라서 다르게 출력하면 어떨까?
// 부모 컴포넌트에서 정의한 자식 컴포넌트의 props를 받기위해서는 아래와 같이 할수있다.
// props는 하나의 인자만 있다.
/*function Btn(props) {
console.log(props)
return (
<button
style={{
backgroundColor: 'brown',
color: 'White',
padding: '10px 20px',
border: 0,
borderRadius: 10,
}}
>
{props.text}
</button>
)
}
*/
// 위 방식 말고 바로 props.text를 받는 방법은 아래와 같다
// {text}를 넣어주면 props.text와 같다.
function Btn({ text, big, bName, displayHello, setDisplayHello }) {
console.log({ text, big, bName })
const handleClick = (event) => {
BtnClick(event, bName, displayHello, setDisplayHello)
}
return (
<button
style={{
backgroundColor: 'brown',
color: 'White',
padding: '10px 20px',
border: 0,
borderRadius: 10,
fontSize: big ? 18 : 10,
}}
onClick={handleClick}
>
{text}
</button>
)
}
function BtnClick(event, bName, displayHello, setDisplayHello) {
console.log(event)
console.log(bName)
if (bName === 'sChange') {
return alert('변경완료되었습니다.')
setDisplayHello(false)
console.log(displayHello)
}
if (bName === 'sConfirm') {
alert('확인되었습니다.')
setDisplayHello(true)
console.log(displayHello)
}
}
function App() {
const [displayHello, setDisplayHello] = React.useState(false)
// component는 항상 첫글자 대문자로
// 부모컴포넌트에 있는 자식 컴포넌트의 properties를 자식 컴포넌트(함수)에 보내서 다르게 출력이 가능하다.
// 자식 props에 있는 것(html의 tag의 type과 같은거)은 마음대로 정의가능하다.(나는 text로 정의한것일 뿐이다.)
return (
<div>
<h1>Your Profile</h1>
<Btn
text="Save Changes"
bName="sChange"
big={true}
displayHello={displayHello}
setDisplayHello={setDisplayHello}
/>
<span> </span>
<Btn
text="Confirm"
bName="sConfirm"
big={false}
displayHello={displayHello}
setDisplayHello={setDisplayHello}
/>
{displayHello && (
<div>
<h3>hello</h3>
</div>
)}
</div>
)
}
const root = document.querySelector('#root')
ReactDOM.render(<App />, root) // 생성한 element를 root인 위치에 그려줌(ReactDOM.render())
</script>
</html>
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Document</title>
</head>
<body>
<div id="root"></div>
</body>
<!-- react import -->
<!-- <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/react@17.0.2/umd/react.development.js"></script>
<script src="https://unpkg.com/react-dom@17.0.2/umd/react-dom.development.js"></script>
<!-- babel import(jsx ->react로 변환) -->
<script src="https://unpkg.com/@babel/standalone/babel.min.js"></script>
<!-- 바벨 사용시 type 입력해주어야 한다. -->
<script type="text/babel">
// props.html에서 계속
// 따라서 버튼 컴포넌트를 만들어서 재활용할 수있다.
// 하나의 컴포넌트(객체와 비슷)에서 자식 컴포넌트 props에 따라서 다르게 출력하면 어떨까?
// 부모 컴포넌트에서 정의한 자식 컴포넌트의 props를 받기위해서는 아래와 같이 할수있다.
// props는 하나의 인자만 있다.
/*function Btn(props) {
console.log(props)
return (
<button
style={{
backgroundColor: 'brown',
color: 'White',
padding: '10px 20px',
border: 0,
borderRadius: 10,
}}
>
{props.text}
</button>
)
}
*/
// 위 방식 말고 바로 props.text를 받는 방법은 아래와 같다
// {text}를 넣어주면 props.text와 같다.
// onClick은 changeValue()함수이다.
function Btn({ text, onClick }) {
console.log(text, ' was render ')
// 여기서 onClick={Method}가 이벤트 리스너이다.
return (
<button
onClick={onClick}
style={{
backgroundColor: 'brown',
color: 'White',
padding: '10px 20px',
border: 0,
borderRadius: 10,
}}
>
{text}
</button>
)
}
// 부모 컴포넌트의 state를 변경하면 당연히 그 자식 컴포넌트들도 Re-render가 일어남.
// 불필요한 렌더링이 발생할 수도 있는데, 이 경우에는 React.memo()로 prop의 변경이 일어난 부분만 렌더링 시킬 수 있음.
// 아주 많은 자식 컴포넌트를 가지고 있는 부모 컴포넌트일 때 사용하면 될 듯.
const MemorizedBtn = React.memo(Btn)
function App() {
// 이번강의에서 <Btn>에 onClick 함수를 추가할것이다.
const [value, setValue] = React.useState('Save Changes')
const changeValue = () => setValue((currnet) => 'Revert Changes')
// 중요 ** 여기서 onClick={changeValue}은 이벤트 리스너가 아니라 props이다!
// React.useState(초기값) 에서 setVariable과 관련된 전체가 다시 렌더링된다.
// 즉, 부모 컴포넌트가 어떤 state값이 변경이 되면 모든 자식 컴포넌트는 다시 그려질 것
//--> react.Memo()를 사용해서 변경된 것만 리렌더링 할수있다.
return (
<div>
<h1>Your Profile</h1>
<MemorizedBtn text={value} onClick={changeValue} />
<span> </span>
<MemorizedBtn text="Confirm" />
</div>
)
}
const root = document.querySelector('#root')
ReactDOM.render(<App />, root) // 생성한 element를 root인 위치에 그려줌(ReactDOM.render())
</script>
</html>
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Document</title>
</head>
<body>
<div id="root"></div>
</body>
<!-- react import -->
<!-- <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/react@17.0.2/umd/react.development.js"></script>
<script src="https://unpkg.com/react-dom@17.0.2/umd/react-dom.development.js"></script>
<!-- prop-type import -->
<!--https://unpkg.com/react-dom@17.0.2/umd/react-dom.development.js을 임포트해야한다. -->
<script src="https://unpkg.com/prop-types@15.7.2/prop-types.js"></script>
<!-- babel import(jsx ->react로 변환) -->
<script src="https://unpkg.com/@babel/standalone/babel.min.js"></script>
<!-- 바벨 사용시 type 입력해주어야 한다. -->
<script type="text/babel">
// props.html에서 계속
// 따라서 버튼 컴포넌트를 만들어서 재활용할 수있다.
// 하나의 컴포넌트(객체와 비슷)에서 자식 컴포넌트 props에 따라서 다르게 출력하면 어떨까?
// 부모 컴포넌트에서 정의한 자식 컴포넌트의 props를 받기위해서는 아래와 같이 할수있다.
// props는 하나의 인자만 있다.
/*function Btn(props) {
console.log(props)
return (
<button
style={{
backgroundColor: 'brown',
color: 'White',
padding: '10px 20px',
border: 0,
borderRadius: 10,
}}
>
{props.text}
</button>
)
}
*/
// 위 방식 말고 바로 props.text를 받는 방법은 아래와 같다
// {text}를 넣어주면 props.text와 같다.
// onClick은 changeValue()함수이다.
// 두번째 매개변수가 특이한데 fontSize =24를 지정하면 프롭을 지정하지 않은 컴포넌트에 fontSize = 24가 추가된다.
function Btn({ text, fontSize = 24 }) {
return (
<button
style={{
backgroundColor: 'brown',
color: 'White',
padding: '10px 20px',
border: 0,
borderRadius: 10,
fontSize: fontSize,
}}
>
{text}
</button>
)
}
// react.js에서는 문제없는 코드라고 인식해서 오류가 출력되지 않는 부분을
// 각 프롭타입을 지정해서 경고문을 볼수 있다. 프롭의 타입을 지정해 놓으면 왜 적용이 안되는지 알수있다.
Btn.propTypes = {
text: PropTypes.string.isRequired,
fontSize: PropTypes.number.isRequired,
}
function App() {
// props를 넘겨줄때 문자는 ="일", ={'일'} || 숫자는 ={1}이렇게 넘겨줄수 있다.
return (
<div>
<Btn text="Save Changes" fontSize={18} />
<Btn text={'continue'} />
<Btn text={14} fontSize={'confirm'} />
</div>
)
}
const root = document.querySelector('#root')
ReactDOM.render(<App />, root) // 생성한 element를 root인 위치에 그려줌(ReactDOM.render())
</script>
</html>
state, component, props 등등 여러가지 용어가 헷갈렸는데, 윤곽이잡히기 시작했고, 또 중요한점은 용어들이 익숙해지지 시작했다.
니코샘이 말씀해 주신것처럼 코드를 이해하고 왜 이렇게 되는거지? 라고 스스로 이해하는 과정이 오래걸린것 같다.
특히 html과 js 그리고 CSS에 대한 공부를 좀더 해야겠다는 생각과 더불어 chatGPT를 활용하는 것도 팁이과 도구라는 것을 깨닫게 되었다.
분할과 정복이라는 개발방식을 이해하고 reactJS 코드를 보니 아 콤포넌트별로 html, JS, Css를 개발할수 있어서 효율적이라는 생각이 들었다.
다시한번 스스로 코드를 보면서 컴퓨터가 이해는 방식을 따라가면서 코드를 이해(디버깅)하는 습관을 가져야 겠다.