지난번 스프린트를 진행하면서, React 자식 컴포넌트에서 부모 컴포넌트 함수 사용하기를 트위터 예제를 통해 구현해보았다.(이전 블로그 포스팅 참조)
이 부분에 대하여 조금 더 자세히 설명하고자 한다.
React에서는 단방향 데이터 흐름이라는 원칙에 따라, 하위 컴포넌트는 상위 컴포넌트로부터 전달받은 데이터의 형태 혹은 타입이 무엇인지만 알 수 있다. 데이터가 state로부터 왔는지, 하드코딩으로 입력한 내용인지는 알지 못한다.
단방향 데이터 흐름인 이유?
--> 단방향 데이터 흐름을 사용하지 않으면 그 때 그 때 기능 변경 사항에 대해서 코드를 계속 작성해야 된다.
--> 코드의 흐름을 알기 쉽다, 복잡하지 않게 된다.
--> 컴포넌트의 중요한 상태만 잘 관리하면
--> 아래에서 UI가 자동으로 변경된다(다소 중앙집권적. 중요데이터 하나가 변경되었을 때, 많은 컴포넌트에 영향을 주는 것을 굳이 작성하지 않아도 된다)
--> 이것이 제일 편한 방법...
하위 컴포넌트에서의 어떤 이벤트로 인해 상위 컴포넌트의 상태가 바뀌는 것에 대하여 React가 제시하는 해결책은 다음과 같다.
상위 컴포넌트의 "상태를 변경하는 함수" 그 자체를 하위 컴포넌트로 전달하고, 이 함수를 하위 컴포넌트가 실행한다
여전히 단방향 데이터 흐름에 원칙에 부합하는 해결방법이다. 바로 이것이 "상태 끌어올리기" 이다.
<Search onSearch={search} />
와 같이 props로 전달하였다.(search함수는 18번째 줄에, 자식컴포넌트는 51번째 줄에 위치해 있다) <input id="input-destination" type="text" value={textDestination} onChange={handleChange}
placeholder="CJU, BKK, PUS 중 하나를 입력하세요" onKeyPress={e => handleKeyPress("ICN", textDestination, e)} />
<button id="search-btn" onClick={()=>handleSearchClick("ICN", textDestination)}>검색</button>
const handleKeyPress = (departure, destination, e) => {
if (e.type === 'keypress' && e.code === 'Enter') {
handleSearchClick(departure, destination)
}
}
const handleSearchClick = (departure, destination) => {
console.log('검색 버튼을 누르거나, 엔터를 치면 search 함수가 실행됩니다')
onSearch({ departure, destination });
// TODO:
}
아래 사진에서 왼쪽 부분, '상태에 영향을 미침'을 설명해주는 부분이다.