저번 글에서 리액트의 기본 개념들을 살펴보았다.
리액트의 작동논리를 알아보면서 어떻게, 어떤게 렌더링되는지 확인했고,
props을 알아보면서 어떻게 데이터를 이동하는지 확인하였다.
그러면서 자동적으로 따라오는 궁금증이 생겼다.
렌더링되는 것은 알겠는데, 우리는 정적인 것만 렌더링하는 것이 아닌, 동적인 것도 렌더링하고 싶다. 어떻게 할까?
props을 통해 상위 컴포넌트 -> 하위 컴포넌트 데이터 이동은 이해했다. 그러면 하위 컴포넌트 -> 상위 컴포넌트 데이터 이동은 어떻게 할까?
이 두가지를 중점적으로 살펴보고, 이와 연관있거나 알아야하는 개념들도 살펴보려한다.
이 글에서 알아볼 것
- React에서 동적인 렌더링 하는법(state)
- 사용자 입력값 컨트롤하기
- 이전 state 활용법
- 데이터 끌어올리기
1. React에서 동적인 렌더링 하는법_State
저번 글에서 살펴본 리액트 작동논리에서 더 깊게 들어가 구체적인 렌더링 방법을 알아보자
- 컴포넌트는 함수다
- 함수가 실행되려면 어디선가, 누군가 함수를 호출해야한다
- react에서는 함수호출(컴포넌트호출)은 상위 컴포넌트등에서 컴포넌트를 임포트하여, 컴포넌트를 사용하는 것을 말한다.
- 그러면 더 이상 호출될것이 없을때까지(최종목표=html) 중첩된 컴포넌트들의 JSX코드를 통과한다
- 그리고 전반적인 결과를 평가하고 DOM 명령어로 변환 후 렌더링한다
- 기서 꼭 기억해야할 점이.. 위의 과정을 마치고나면 리액트는 다신 반복하지않는다
- 즉, 처음 실행했을때 모든것을 평가 및 렌더링하고 나면 끝이다.
- 그렇다면, 화면에 보이는것을 업데이트 하고 싶을때는 어떻게 할까?
- State 도입
- 함수가 실행되려면 어디선가, 누군가 함수를 호출해야한다
구체적인 렌더링 방식을 살펴보니, 리액트는 기본적으로 처음 평가후 재평가를 하지 않는다.
하지만, 현대적인 웹페이지등은 변화에 반응하고 인터페이스를 업데이트하는 것은 필수이다.
이때 사용되는 개념이 State이다.
- State
- react는 일반 변수의 값이 변경되어도 신경쓰지않는다(재렌더링을 실행하지않는다)
- 대신 react는 useState라는 훅을 이용해 값을 저장하고, 그 값이 변경되면 재렌더링을 실행한다
- const [curState, setCurState] = useState(initState);
- useState는 하나의 인자를 받는데, 그것이 초기값이다(initState)
- useState를 통해 두개의 값을 얻을수있는데, [현재값, 업데이트함수]다 ([curState, setCurState])
- state가 변할때마다 업데이트함수를 호출한다
- 또한 이러한 state를 JSX코드에 사용하게되면 react는 그 state가 바뀔때마다 재렌더링을 실행한다
*참고
각 컴포넌트들은 독립적인 state를 가지고있다(같은 컴포넌트라도 두 번 사용하면 사용한곳마다 독립적인 state를 갖음)
2. 사용자 입력값 컨트롤
웹페이지은 대부분 사용자 입력값을 활용한다.
리액트에서 사용자 입력값을 활용하는 방법을 알아보자
- <input type="text" onChange={AHandler}></input>
- input 태그의 onChange라는 속성은 모든 키입력(사용자 입력)에 트리거된다
- 따라서 onChange={AHandler} 에서 AHandler라는 함수가 모든 키입력에 대해서 실행된다
- 사용자 입력값을 얻는법
- onChang는 자동적으로 event 객체를 가지고있고, event 객체에는 target이라는 프로퍼티를 가지고있다.
- 이 target은 키입력 값을 value로 저장하고있다.
- 따라서 사용자 입력값은 event.target.value로 접근할 수 있다
- 양방향 바인딩
- input 태그에는 value라는 속성이 존재하는데, 이는 value에 바인딩 값을 새로운 값으로 설정해준다
3. 이전 State 활용법
가끔 state를 작업하다보면, 기존(이전)의 state를 유지하고 새로운 state를 오버라이드하거나 추가하는 경우가 생긴다.
이때 useState에서 이전 state를 활용하는 방법은 함수를 이용하는 것이다
const [userInput, setUserInput] = useState({
title: "",
amount: ""
});
const titleInputHandler = (e) => {
/*
setUserInput({
...userInput,
title: e.target.value
})
*/
setUserInput((prevState) => {
return {
...prevState,
title: e.target.value
}
});
}
- 왜 주석처리된 부분처럼 처리하면 안될까?
- react는 상태 업데이트 스케쥴을 갖고있어서 바로 업데이트를 실행하지 않는다, 따라서 만약 수많은 상태 업데이트를 진행한다면 잘못되었거나 오래된 스냅샷에 의존할수도있다
- 함수처리 방식은 react가 prevState(스냅샷)이 최신 상태의 스냅샷이라는 것과 항상 계획된 상태 업데이트를 염두에 두고 있다는 것을 보장해준다
4. 데이터 끌어올리기
props를 이용하면 상위 컴포넌트에서 하위컴포넌트로 데이터를 전달할 수 있다는 것 까지는 확인했다. 그러면 반대는 어떻게 할까?
*참고
react 규칙 중 하나인 컴포넌트간의 통신은 상하관계만 가능하다라는 점을 주목하자
- 컴포넌트에 자체 이벤트 속성 이용
- onChange={함수} 처럼 내장된 이벤트 속성이 있는 것 처럼 자체 이벤트 속성을 만들 수 있다.
- 이런 이벤트 속성은 함수를 가질수있고, 상위 컴포넌트로부터 하위 컴포넌트로 함수를 전달할 수 있게 해줄 것이다
- 그러면 하위 컴포넌트에서는 해당 함수를 호출할 수 있다
- 그 함수에 매개변수로 데이터를 전달할 수 있다
예를들어
ExpenseForm 데이터 → NewExpense → App으로 이동하는 예제를 살펴보자
// App.js
const addExpenseDataHandler = (expense) => {
console.log(expense);
};
<NewExpense onExpense={addExpenseDataHandler}></NewExpense>
// NewExpense.js
const saveExpenseDataHandler = (enteredExpenseData) => {
const expenseData = {
...enteredExpenseData,
id: Math.random().toString(),
};
props.onExpense(expenseData);
};
<ExpenseForm onSaveExpenseData={saveExpenseDataHandler}></ExpenseForm>
// ExpenseForm.js
const expenseDate = {
title: enteredTitle,
amount: enteredAmount,
date: new Date(enteredDate),
};
props.onSaveExpenseData(expenseDate);
'OLD > React' 카테고리의 다른 글
[React] React에서 사용자 입력을 컨트롤 하는 두 가지 방법 (state vs ref) (0) | 2023.02.26 |
---|---|
[React] React 여러 기능들 (Fragment, Portal) (0) | 2023.02.25 |
[React] React "key" prop (react에서 배열 활용 시 발생하는 Warning 해결하기) (0) | 2023.02.24 |
[React] React 스타일링 하는 방법 3개 (인라인&일반CSS, styled-components, CSS 모듈) (0) | 2023.02.23 |
[React] React 기본 개념(컴포넌트, JSX, props...) (0) | 2023.02.20 |