Fragment
리액트에서 하나의 컴포넌트가 여러개의 엘리먼트들을 반환
JSX를 사용할 때 return 문 안에는 반드시 하나의 최상위 태그가 존재
리액트는 하나의 컴포넌트만을 리턴
최상위 태그를 div로 할 경우 의미없는 태그가 추가됨
이를 피하기 위해서 fragment태그 사용하여 실제 HTML 요소가 DOM에 렌더링되지 않도록
단축문법
<Fragment> </Fragment>
대신 <> </>
사용 가능Portals
랜더된 HTML 컨텐츠를 다른 곳으로 이동 시키는 것
기존의 Modal창을 div
에서 전체 페이지를 사용한 Portal
로 변경하기
public/index.html에 추가
<body>
<div id="backdrop-root"></div>
<div id="overlay-root"></div>
<div id="root"></div>
</body>
const Backdrop = (props) => {
return <div className={classes.backdrop} onClick={props.onConfirm} />
}
const ErrorModal = (props) => {
return (
<React.Fragment>
{ReactDOM.createPortal(
<Backdrop onConfirm={props.onConfirm} />,
document.getElementById('backdrop-root')
)}
{ReactDOM.createPortal(
<ModalOverlay
title={props.title}
message={props.message}
onConfirm={props.onConfirm}
/>,
document.getElementById('overlay-root')
)}
</React.Fragment>
)
}
Refs
값만 읽고 아무런 수정없는 경우, state가 필요없는 경우
form을 submit할 때 input의 value로 사용자 입력을 받은 키스트로크 값을 업데이트하고 상태에 저장한다.
state로 input의 value를 관리하기 때문에 input에서 키보드 입력을 할 때마다 state가 변하게 되고,
state가 변함에 따라, UI를 업데이트하기 위해 re-rendering이 계속 일어난다
상태를 업데이트 하는 일은 폼을 제출할 때마다 필요한 것인데 불필요하게 키스트로크 마다 렌더링하는 것을 막기 위해 refs가 필요하며
refs는 React 시스템이 해당 요소를 관리하지 않도록 해준다
ref가 input을 가리키도록 변경하면
input은 state를 변경하지 않기에 불필요한 re-rendering은 일어나지 않는다.
import React, { useState, useRef } from 'react'
const AddUser = (props) => {
const nameInputRef = useRef()
const ageInputRef = useRef()
const addUserHandler = (event) => {
// refs로 DOM 조작하기
const enteredName = nameInputRef.current.value // React없이 DOM에 접근하여 유저가 입력한 값을 초기화
const enteredUserAge = ageInputRef.current.value
}
return (
<Wrapper>
<Card className={classes.input}>
<form onSubmit={addUserHandler}>
<label htmlFor="username">Username</label>
<input id="username" type="text" ref={nameInputRef} />
<label htmlFor="age">Age (Years)</label>
<input id="age" type="number" ref={ageInputRef} />
<Button type="submit">Add User</Button>
</form>
</Card>
)
}
Input 값 초기화하는 두가지 방법
refs로 DOM 조작하기 (거의 사용 X)
state-based (기본)