리액트가 실행이 되면 JSX 파일 및 함수가 전부 읽혀지고 화면에 렌더링 해주는 방식이라 렌더링 된 후에 데이터가 변경되거나 화면이 변경되면 리액트는 그걸 인지하지 못 합니다. 그래서 리액트에 다시 알려줘야 하는데 그러기 위해 사용하는 것이 state 입니다.
State 사용법
const [name(현재상태 값), setName(값을 변경해주는 함수)] = useState(props.name(초기값을 할당하는 곳));
state 값 변경하는 방법
위에서 설명했듯이 state 값은 setState 함수를 이용하여야 합니다. setState 함수를 이용하여 값을 변경해야지만 react가 state 값이 변경되었다는 것을 인식하여 화면을 렌더링 하기 때문 입니다.
state 변경 시 값 주의점
예를들어 setState(3)을 하게 된다면 state 값은 3으로 변경되면서 렌더링이 되겠지만, state = 3이라고 하면 값은 변경이 되겠지만 렌더링이 되지 않습니다. 이점을 주의하여 state 값을 사용하여야 합니다.
setState 시 이전 state 값 사용 방법
state는 number, string, boolean 등 1개의 자료형을 넣을 수 있지만, 배열이나 객체와 같은 것도 사용할 수 있다. 아래 예시를 확인해 봅시다.
const [userInput, setUserInput] = useState({
enteredTitle: '',
enteredAmount: '',
enteredDate: ''
});
위 state는 과일 state이다. 여기서 name만 딸기로 변경하고 싶은 경우 여러가지 방법이 있다. 3가지 방법을 확인해보자. 첫번째는 새로운 객체를 만들어서 setFruit 하는 방법. 두번째는 fruit state를 이용하여 name만 변경하는 방법. 세번째는 prevState를 이용하여 이전 state 값을 사용하여 setState를 하는 방법이 있습니다.
1. 새로운 객체를 만들어서 setFruit 하는 방법
setUserInput({ name:"Ryan", age:20, hobby:"Swimming" })
2. fruit state를 이용하여 name만 변경하는 방법
setUserInput({ ...userInput, hobby:"Swimming" })
3. prevState를 이용하여 이전 state 값을 사용하여 setState를 하는 방법
setUserInput((prevState) => {
return { ...prevState, enteredTitle: event.target.value }
})
리액트는 상태를 업데이트할 때 스케줄 방식을 채택하여 업데이트를 시키기 때문에 동시에 수많은 양의 상태를 업데이트하게 되면 오래되거나 잘못된 데이터를 의존할 수 있어 문제가 발생할 수 있습니다 그렇기 때문에 2번째 방법보다는 3번째 방법을 사용하는 것을 추천드립니다. 그 외에 1번과 3번은 사용자가 가장 편하다고 생각되는 방식을 사용하면 됩니다.
state를 사용한 양반향 바인딩 구현 법
<input
type='text'
value={enteredTitle}
onChange={titleChangeHandler}
/>
value 속성은 input 요소의 현재 값을 설정하며, 이 값은 state나 props와 같은 상위 구성 요소의 데이터를 참조할 수 있습니다.
onChange 이벤트 핸들러 함수는 input 요소의 값이 변경될 때마다 호출되며, 이 함수에서 상위 구성 요소의 state나 props를 업데이트하여 input 요소와 상위 구성 요소 간의 데이터를 동기화할 수 있습니다.
따라서, 위 코드에서 value 속성은 enteredTitle 상태 값을 참조하고, onChange 이벤트 핸들러 함수는 titleChangeHandler 함수를 참조합니다. 이로 인해, 입력된 값을 실시간으로 반영하면서 양방향 데이터 바인딩을 구현할 수 있습니다.
리액트 중괄호 안에 함수를 넣었을때 ()를 넣지 않는 이유
리액트에서 <div OnClick = { fun }> 중괄호 안에 함수를 넣었는데 (함수)fun 앞에 괄호가 없는 이유는 만약 fun() 이렇게 사용하게 되면 리액트가 실행이 되면서 JSX 파일이 전부 읽어질때 함수도 같이 실행이 되어서 버튼을 클릭한 뒤 실행이 되는게 아닌 런타임이 실행되면서 함수로 처리되서 실행되기 때문에 괄호를 넣지 않는것이다.
부모 컴포넌트에 자식 컴포넌트의 데이터를 binding 하는 법
부모 컴포넌트
import ChildComponent from './ChildComponent';
// (1-1번) 부모 컴포넌트의 함수
const ParentChangeHandler = (childParamsData) => {
const childData = {
...childParamsData
}
// (4번) 부모 컴포넌트에 데이터가 전달된다.
console.log(childData); // title: 타이틀 입니다. , amount:450 , date:2023년 4월 13일
}
const ParentComponent = () => {
return (
<div>
//(1-2번) 자식 컴포넌트에게 부모 컴퍼넌트 함수를 전달
<ChildDate onParentChangeHandler={ParentChangeHandler}/>
</div>
)
}
1. 부모 컴포넌트의 함수를 자식 컴포넌트에 보낸다.
자식 컴포넌트
const ChildComponent = (props) => {
...
// 버튼 클릭 시 실행되는 핸들러
const submitHandler = (event) => {
event.preventDefault();
// 부모 컴포넌트로 보낼 데이터 (ChildData)
const childData = {
title: enterTitle,
amount: enterAmount,
date: new Date(enterDate),
}
//(2번) 부모 컴포넌트의 함수를 호출 후 인수에 보낼 데이터 작성
props.onParentChangeHandler(childData)
}
return <form onSubmim={submitHandler}>
<label>Title</label>
<input type='text'
value={enterTitle || ''}
onChange={titleChangeHandler}
/>
<label>Amount</label>
<input type='number'
min="0.01"
step="0.01"
value={enterAmount || ''}
onChange={amountChangeHandler}
/>
<label>Date</label>
<input type='date'
min="2019-01-01"
max="2022-12-31"
value={enterDate || ''}
onChange={dateChangeHandler}
/>
<div className='new-expense__actions'>
// (3번) 해당 함수를 실행한다.
<button type='submit'>App Expense</button>
</div>
</form>
}
2. 자식 컴포넌트에서 부모 컴포넌트에게 받은 함수에 인수로 보내려고 하는 데이터를 작성 한다.
3. 해당 함수를 실행한다.
4. 부모 컴포넌트에게 데이터가 전달된다.
JSX 문법에서 And 연산자 활용하는 법
filteredExpenses.length === 0 && <p>데이터가 없습니다.</p> : &&(And연산자) 뒤에 있는 구문이 true 이면 &&(And연산자) 앞에 있는 구문이 실행된다.
이것보다 JSX를 조금더 보기 쉽게 만들어주는 구문은 아래처럼 변수에 문장을 담아주는 것 이다.
let contextExpress = <p>데이터가 없습니다.</p>
if(filteredExpenses.length > 0) {
contextExpress = filteredExpenses.map((items) =>
<ExpenseItem
key = {items.id}
title = {items.title}
amount = {items.amount}
date = {items.date}
/>)
}
'프로그래밍 > React' 카테고리의 다른 글
React + Typscript에 AOS 라이브러리 사용법 (0) | 2023.07.24 |
---|---|
React-csv 패키지 사용법 (0) | 2023.05.15 |
React useEffect 란? (0) | 2023.05.08 |
React useReducer란? (0) | 2023.05.08 |
React ref 란? (0) | 2023.04.27 |