✍️ Hello컴포넌트에 name
값을 전달해주고, Hello컴포넌트에서 name
값을 사용해보자.
// App.js
import React from 'react';
import Hello from './Hello';
import './App.css';
function App() {
return <Hello name='seul' />;
}
export default App;
// Hello.js
import React from 'react';
function Hello(props) { // 파라미터로 props를 받아오자.
return <div>안녕하세요 ! {props.name}</div>;
}
export default Hello;
props.name
을 통해서 name의 값을 조회할 수 있다.📌 구조 분해 (비구조화 할당) 문법
function Hello({ color, name }) {
return <div style={{ color }}>안녕하세요 ! {name}</div>;
}
❓ return 에서 중괄호가 이중으로 들어가는 것과 파라미터로 비구조화 할당이 이루어지는 것처럼 보이는 부분이 궁금했다.
const object = { a: 1, b: 2 };
function print({ a, b }) {
console.log(a); // 1
console.log(b); // 2
}
print(object);
defaultProps
를 이용할 수 있다.function App() {
return (
<>
<Hello name='seul' color='blue' />
<Hello color='skyblue' />
</>
);
}
function Hello({ color, name }) {
return <div style={{ color }}>안녕하세요 ! :) {name}</div>;
}
Hello.defaultProps = {
name: 'default로 설정된 이름입니다.',
};
Prop에 어떤 값도 넘기지 않을 경우, 기본값은 true이다. 아래의 두 JSX 표현은 동일한 표현이다. (일반적으로 prop에 대한 값을 전달하도록 권장한다.)
<MyTextBox autocomplete />
<MyTextBox autocomplete={true} />
props.children
이라는 특수한 prop으로 넘겨진다.props.children
을 조회한다.// App.js
function App() {
return (
<Wrapper>
<Hello name='seul' color='blue' />
<Hello color='skyblue' />
</Wrapper>
);
}
// Wrapper.js
function Wrapper({ children }) { // 받아와서
const style = {
border: '3px solid pink',
padding: '16px',
};
// props.children을 렌더링 해줘야 한다.
return <div style={style}>{children}</div>;
}
❓ state는 언제 사용할까? 🤔
▶ 변동시 자동으로 html에 반영되도록 만들고 싶을 때 사용한다.
📌 Hook
기존의 함수형 컴포넌트에서 state와 라이프사이클 메소드를 잘 이용할 수 있게 만들어진 것
✍️ 사용법 3단계
1) import {useState}
2) useState(보관할 자료)
3) let[작명, 작명]
useState() 함수를 호출하면 배열을 반환한다.
- 1 번째 원소는 현재 상태 값 변수
- 2 번째 원소는 상태 값을 갱신해주는 Setter 함수
- useState 괄호 안의 값은 상태의 초기 값
import React, { useState } from 'react'; // 1)
function Counter() {
const [number, setNumber] = useState(0); // 2)
const onIncrease = () => {
setNumber(number + 1); // 3)
};
const onDecrease = () => {
setNumber(number - 1); // 3)
};
return (
<div>
<h1>{number}</h1>
<button onClick={onIncrease}>+1</button>
<button onClick={onDecrease}>-1</button>
</div>
);
}
export default Counter;
useState
라는 함수를 불러와 준다.useState
를 사용할 때 기본값을 파라미터로 넣어서 호출한다. 함수를 호출하면 배열이 반환되며, 첫 번째 원소는 현재 상태, 두 번째 원소는 Setter함수 이다.const numberState = useState(0);
const number = numberState[0];
const setNumber = numberState[1];
📌 여기서 setNumber 가 하는 역할
(1) number의 값을 변경하는 것 + (2)이 함수를 다시 실행하는 것
const onIncrease = () => {
setNumber((prevNumber) => prevNumber + 1);
};
const onDecrease = () => {
setNumber((prevNumber) => prevNumber - 1);
};
❓ 3)의 두 가지 방식의 차이가 궁금해서 공식 사이트를 찾아보았다.🤔 ▼ setState()는 컴포넌트 state의 변경 사항을 대기열에 집어넣고, React에게 해당 컴포넌트와 그 자식들이 갱신된 state를 사용하여 다시 렌더링되어야 한다고 알린다. 이벤트 핸들러와 서버 응답 등에 따라서 UI를 갱신할 때 많이 사용한다.
setState() 는 컴포넌트 갱신에 있어서 즉각적인 명령이 아닌 요청이다. 따라서 React는 이 메서드의 실행을 지연시키고 여러 컴포넌트를 한번에 갱신할 수도 있다.
때문에 React는 state 변화가 즉시 적용되는 것을 보장하지 않는다. 즉 setState()는 컴포넌트를 항상 즉각적으로 갱신하지는 않는다.
❓그렇다면 의도치 않은 결과가 나올 수 있다는 말 같은데..
✍️ 그 대신에 componentDidUpdate 또는 setState의 콜백(setState(updater, callback))을 사용할 수 있다고 한다. 둘 다 갱신이 적용된 뒤에 실행되는 것이 보장된다고 한다. useState()도 같은 맥락으로 이해했다!
📌 참고한 페이지
React.Component_ setState()
setState()
✍️ 정리하자면..
setState 함수는 두 가지가 있다.
1. setState(newState)
2. setState(prevState => { return newState; })
- 컴포넌트 내의 state 값에 의존해서 계산할 때, 값을 setState(updated)
로 설정하기 보다는, setState(prevState => newState)와 같이 state 값을 받아서 업데이트 되는 state값을 만드는 arrow 함수를 호출하는 게 좋다고 한다.😀
{}
전체가 계속 반복 호출된다.function InputSample() {
const [text, setText] = useState(''); // 1)
const onChange = (e) => { // 3)
setText(e.target.value); // 4)
};
const onReset = () => {
setText('');
};
return (
<div>
<input onChange={onChange} value={text} /> // 2)
<button onClick={onReset}>초기화</button>
<div>
<b>값: {text}</b>
</div>
</div>
);
}
onChange
라는 이벤트를 사용, 이 객체의 e.target
은 이벤트가 발생한 DOM인 inputDOM을 가리키게 된다.e.target.value
를 통해서 input에 들어온 value 값을 알 수 있다.e
와 e.target
을 확인해보자.▼input이 여러개일 경우 또 다른 이벤트 핸들러 함수를 만드는 것 보다 input
태그의 name
속성을 이용하는 방법이 있다.
function InputSample() {
const [inputs, setInputs] = useState({
name: '',
age: '',
});
const { name, age } = inputs; // 비구조화 할당을 통해 값을 추출한다.
const onChange = (e) => {
const { value, name } = e.target; // 2) e.target에서 name과 value를 추출한다.
setInputs({
...inputs, // 기존의 input 객체를 복사한다.
[name]: value, // 📌
});
};
const onReset = () => {
setInputs({
name: '',
age: '',
});
};
return (
<div>
// 1)
<input name='name' placeholder='이름' onChange={onChange} value={name} />
<input name='age' placeholder='나이' onChange={onChange} value={age} />
<button onClick={onReset}>초기화</button>
<div>
<b>값: </b>
{name} ({age})
</div>
</div>
);
}
1) return 안쪽의 각 input
에 name
값을 부여해서 각 input
을 구분할 수 있게 되었다.
2) 이 값은 e.target.name
을 통해서 조회할 수 있다.
📌 ) 이 부분이 이해가 잘 되지 않아서 여러 자료를 찾아보았다. 🧐
코드의 의미는 이렇다. → name키를 가진 값을 value로 설정한다.
이 코드는 [e.target.name]: e.target.value
와 동일하다.
key 부분에 []
괄호가 사용된 것을 알아보자! ▼
계산된 프로퍼티(속성)명
프로퍼티의 이름을 정의하는 새로운 방법
{[expression]: value}
객체 리터럴의 프로퍼티명 자리에 대괄호[]
와 표현식의 조합으로 사용한다. expression의 실행 결과가 프로퍼티의 이름이 된다.
프로퍼티명을 그대로 사용하는 경우 ▼
const obj = {name:'hi', age:15}
const newObj = {...obj, name: 'seul'}
console.log(newObj) // {name: 'seul', age: 15}
표현식을 프로퍼티 명으로 활용하려는 경우 ▼
const obj = {name:'hi', age:15}
const props = 'name';
const newObj = {...obj, [props]: 'seul'}
console.log(newObj) // {name: 'seul', age: 15}
✍️ 예시)
// ex.1)
let name = 'seul';
let obj = {
[name]: 123
};
obj; // Object { seul: 123 }
// ex.2)
let i = 0
let a = {
['foo' + ++i]: i,
['foo' + ++i]: i,
['foo' + ++i]: i
}
console.log(a.foo1) // 1
console.log(a.foo2) // 2
console.log(a.foo3) // 3
// ex.3)
const items = ["A","B","C"];
const obj = {
[items]: "Hello"
}
console.log(obj); // A,B,C: "Hello"
console.log(obj["A,B,C"]) // "Hello"
✍️ 예시를 보면 전부 객체의 [key]
가 계산되어진 프로퍼티명으로 사용된 것을 알 수 있다.
❗️ 즉, 궁금했던 예제에서의 경우 ▼
const onChange = (e) => {
const { value, name } = e.target;
setInputs({...inputs, [name]: value,});
};
첫번째 input 에 변경이 발생하면 [name]
에 name 이 들어간다.
두번째 input 에 변경이 발생하면 [name]
에 age 가 들어간다.
그래서 만약 []
없이 name
으로만 적게되면 age에 대한 값은 업데이트 되지 않을 것이다.
😀 기본적인 문법이 헷갈리면 쉬운 구간에서도 막힐 수 있으니 그때 그때 잘 숙지해두자!
reference)
React-JSX
React-setState()
setState()
vlpt-props,useState
dreamcoding
MDN-Computed property names
JS_Computed property names