이제까지 봐왔지만 JSX는 한개의 루트요소만 리턴할 수 있다.
다음과 같은 코드는 리턴될 수 없다.
return(
<h2>Hi there!</h2>
<p>This does not work</p>
)
<div>
태그로 감싸기,
로 연결해주어야 한다.key
값을 할당해주어야 한다.그렇다면 왜 첫번째 해결책을 그대로 쓰려고 하지 않을까?
<div>
태그가 중첩될 수도있다.
div
태그로 감싸는 것 보다 다음과 같은Wrapper
컴포넌트로 만들어서 감싸면div
를 중첩시키지 않을 수 있다.
const Wrapper = (props) => {
return props.children;
};
export default Wrapper;
이 작업을 해주는 내장된 기능이 있다.
<> </>
이것은 프로젝트 셋업이 되어있어야 사용이 가능하다.<React.Fragment>
이건 모든 프로젝트에 적용 가능하다.import {Fragment} from 'react';
를 한 후에<Fragment> </Fragment>
로 사용해도 무방하다. 오버레이 컴포넌트, 즉 이전에 만들었던 프로젝트에서 백드롭이나 모달창 같은 컴포넌트는 구조상 가장 위에 있어야 한다.
이전 프로젝트를 보면 다음과 같은 구조를 가지고 있다. 하지만 이는 기능적으로 문제는 없으나, 의미론적인 문제가 있다. 이것은 리액트돔 라이브러리의 portals
를 이용해서 해결할 수 있다.
다음과 같이 해결해 보자
import ReactDom from "react-dom";
import 해준다.index.html
파일 안에 <div id="modal"></div>
코드를 추가 한다.ReactDom.createPortal()
을 통해서 렌더링 할 위치를 변경시킨다.ReactDom.createPortal(
<ErrorModal message={error} onDeleteModal={modalHandler} />,
document.getElementById("modal")
)
UserInput
단계에서 이름과 나이를 입력받는 곳을 업데이트 하는 방식은onChange
와useState
를 이용했다. 그런데 키보드 입력을 할때마다 업데이트 하는 방식은 효율적이지 못하다. submit을 눌렀을 때 최종 값만 필요하기 때문이다. 이 문제는Refs
를 이용해서 해결할 수 있다.
import React, { useState, useRef } from "react";
useRef 을 import 해준다.
const nameInputRef = useRef();
const ageInputRef = useRef();
input
의 props
에 ref
를 추가 해준다.
<input
type="text"
onChange={updateName}
value={enteredName}
ref={nameInputRef}
></input>
그러면 submit
을 눌렀을 때 최종 값을 컨트롤 할 수 있다.
const enteredUserName = nameInputRef.current.value;
이 값이 input에 들어있는 값이다.
이렇게 되면 Add User
버튼을 눌렀을 때, input
이 초기화 되지 않는다. 직접 DOM을 건드려서는 안되지만 편법을 이용해서
nameInputRef.current.value = '';
할수는 있다.
input 내부가 리액트에 의해서 컨트롤 된다 -> 제어되는 컴포넌트 (State)
input 내부가 리액트에 의해서 컨트롤 x -> 제어되지 않는 컴포넌트(Ref)