리액트에서는 일반적으로 jsx에서는 루트 jsx 요소는 1개여야 합니다. 따라서 값을 반환하거나 값을 변수 또는 상수 또는 속성에 저장하려면 그 값은 반드시 jsx 요소 1개여야 합니다.
그래서 해결하는 방법중에 가장 간편한 방법은 <div></div> 태그로 감싸는 것입니다.
하지만 이 방법은 이상적인 방법이 아닙니다. 스타일링을 꼬일 수 있게 하고, 앱을 느려지게 할 수도 있습니다.
해결방법
components 폴더 안에 Helpers 폴더를 생성한다.
Wrapper.js 파일을 생성후 props.children;을 리턴한다.
칠드런 프롭스는 사용자 정의 컴포넌트에서 여는 태그와 닫는 태그 사이에 넣어준 모든 내용을 담고 있습니다.
여는 태그와 닫는 태그 사이에 있는 내용을 반환하는 컴포넌트는 유효합니다.
AddUser.js 파일에 임포트 한다.
Wrapper 컴포넌트는 일반적인 리액트 컴포넌트로 사용할 수 있습니다.
div태그 대신에 Wrapper로 바꿔줍니다.
방금전까지 div태그는 JSX의 스타일 없이 요구 사항만 충족하고 있었습니다.
Wrapper 컴포넌트가 하는 일은 props.children을 반환하는 것뿐입니다.
하지만 JSX 요구 사항을 충분히 충족시킵니다.
좋은 점은 실제 DOM으로 렌더링되지 않는다는 점입니다.
약간의 속임수를 사용하여 요구사항을 충족시키고 div 수프에 빠지지 않았습니다. 이건 너무 편리하고 일단 알고 나면 너무 당연하기 때문에 이 Wrapper 컴포넌트를 우리가 직접 만들 필요가 없습니다. 이것은 리액트에서 함께 제공됩니다.
프래그먼트 컴포넌트 입니다. React.Fragment로 접근 할 수 있어요 또는 리액트에서 프래그먼트를 임포트해도 됩니다. 일부 프로젝트에서는 <> 태그에 공백을 넣어 짧게 쓸 수 도 있습니다. 이건 프로젝트 설정에 따라 다릅니다. 빌드 워크플로가 이를 지원해야 하기 때문입니다. React.Fragment는 항상 작동합니다.
두 가지다 실제 HTML요소를 DOM에 랜더링하지 않습니다.
프래그먼트를 사용하면 더 깔끔한 코드를 작성할 수 있습니다. 최종페이지에 불필요한 HTML 요소들이 줄어듭니다.
리액트에는 포털이라는 개념이 있다.
포털에는 두 가지가 필요합니다. 컴포넌트를 이동시킬 장소가 필요하고요 그런 다음 컴포넌트에게 그 곳에 포털을 가져야 한다고 알려줄 필요가 있습니다.
public 폴더의 index.html 파일로 들어갑니다.
그리고 div를 작성합니다. 왜 작성을 하냐면 나중에 이 장소를 찾아오는 데 사용합니다.
이제 ErrorModal.js 파일로 돌아와서 backdrop이 어딘가로 포탈되어야 한다고 알려줘야합니다.
상수를 하나 추가합니다. 이름은 Backdrop으로 하고요. 이것은 새로운 컴포넌트가 될 겁니다.
동일한 파일에 추가하는데요. 그 이유는 이 앱에서 이 Backdrop 컴포넌트는 모달과 함께 사용하기만 할 것이기 때문입니다. 따라서 모든 컴포넌트를 하나의 큰 파일에 저장하겠습니다. 그러나 여러 컴포넌트 파일로 나눌 수도 있습니다.
특히 백드롭을 다른 컴포넌트들과 함께 사용한다면요.
props를 가져오고 Backdrop 클래스를 가져오는 div를 반환합니다.
두 가지로 나눴습니다. 이렇게 해야 포털을 사용하기 쉽기 때문입니다.
react-dom을 임포트 합니다.
이제 ReactDom에서 creactPortal 메서드를 호출할 수 있습니다.
creactePortal 메소드는 두 개의 인수를 취하는데요.
첫 번째는 렌더링되어야 하는 리액트 노드입니다. JSX여야 합니다.
두 번째 인수는 포인터 입니다.
이 요소가 렌더링되어야 하는 실제 DOM의 컨테이너를 가리키는 포인터죠.
이 경우에는 backdrop-root 컴포넌트로 렌더링하고 싶죠.
브라우저에서 제공하는 API를 사용하면 됩니다.
이 API를 사용하여 실제 DOM 요소에 접근하는 거죠.
리액트에 의해 이미 렌더링된 기존 애플리케이션 내부로 포털시킵니다.
렌더링하려는 HTML 내용을 다른 장소로 이동시키는 거죠 .
onClick 가 아니라 onConfirm입니다.
왜냐하면 Backdrop 안에서 onConfirm을 사용했으니까요 따라서 onConfirm 프롭을 설정해야 했습니다.
ModalOverlay를 마저 작성해줍니다.
root 밖으로 렌더링 되었죠? 이것이 포털입니다.
포털의 핵심은 렌더링된 HTML 내용을 다른 곳으로 옮기는 거죠.
ref
ref는 reference의 줄임말로 참조라는 뜻입니다. 리엑트에서는 ref로 사용합니다.
AddUser.js 파일을 보면 인풋에 입력할때마다 state를 업데이트 합니다. 조금 과한 거 같습니다. 그래서 ref를 사용해서 입력이 끝난 다음 Add User 버튼을 누를때 ref로 입력값을 받아올 겁니다.
사용하는 방법은 useRef 훅을 사용합니다.
그리고 함수형 컴포넌트 안에서
useRef를 호출하면 됩니다.
input태그에 가서 이름과 나이를 연결해줍니다.
add 핸들러 밑에
console.log()를 찍어본다.
add 버튼을 클릭하면
항상 current 프롭을 갖고 있는것을 볼 수 있다.
currnet 프롭은 그 ref가 연결된 실제 값을 갖습니다.
current.value를 읽을 수 있습니다.
Max를입력하고 버튼을 클릭하면 console.log에 찍히는걸 볼 수 가 있다.
나이도 추가하여 작성합니다.
유효성 검사를 변경합니다.
마지막 상위 컴포넌트에 넘결 데이터도 바꿔줍니다.
그리고 이름과 나이에 관한 state를 삭제합니다.
이렇게 하면 초기화 시키는 로직이 없습니다.
자주 쓰이는 방법은 아니지만 괜찮은 방법이 있긴합니다.
그렇지면 이 방법은 DOM을 직접 조작을 하는 것이니깐 일반적으로는 이렇게 하면 안됩니다.
nameInputRef.current.value = '' 를 통해 빈 공백을 줍니다.
그럼 state랑 ref중 어떤것을 써야 하나면
예를 들어 값을 빠르게 읽고 싶을 때가 있을 건데요
값만 읽고 싶다면 아무 것도 바꿀 계획이 없다면 state는 그리 필요없죠.
state를 키 로그 기록용으로 사용하는 건 별로 좋지 않습니다. 불필요한 코드와 작업이 많습니다. 따라서 값만 읽고 싶다면 ref가 더 나을 겁니다.
'React > React 완벽 가이드' 카테고리의 다른 글
useCallback (0) | 2023.09.15 |
---|---|
불필요한 재평가 방지하기 (0) | 2023.09.15 |
React 완벽 가이드 섹션 8 : 연습하기 (0) | 2023.02.27 |
React 완벽 가이드 섹션 7 : 리액트 앱 디버깅하기 (0) | 2023.02.26 |
React 완벽 가이드 섹션 6 : 리액트 컴포넌트 스타일링(2) (0) | 2023.02.24 |