You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
BrowserRouter 안에 Routes를 감싸는 Switch 컴포넌트 이름이 Routes로 변경되며 경로 매칭 알고리즘이 향상되었다.
Route 컴포넌트에서 exact prop이 지정하지 않아도 default가 되었고, 순서에 상관없이 정확한 경로를 찾아 라우팅해준다.
이전에는 children, component라는 prop을 통해 경로에 따라 렌더링 할 컴포넌트를 받았었는데, 이제는 element라는 prop으로 받는다.
이전에는 component prop으로 경로에 따라 렌더링할 컴포넌트를 전달하는 경우 컴포넌트 함수참조값만을 전달하면서, prop을 전달하기 어려웠다.
render props pattern이나 HOC으로 prop를 전달해야만 했다.
e.g. <Route component={Signin} /> 이렇게는 프롭전달 못하니까 아래 방법들을 사용가능 but 복잡귀찮
render prop을 쓰는 방식으로 <Route render={(prop) => <Signin prop={myprop}/>} />
RRD가 제공하는 HOC withRouter로 해당 컴포넌트를 감싸면, 하위 컴포넌트에 Router에서 전달받는 특정 데이터를 전달할 수 있다. forwardRef처럼 감싸서 export하면 컴포넌트를 호출하는 곳에서 전달하는 데이터를 접근할 수 있다.
이젠 prop을 넣은 JSX 문법으로 쓴 컴포넌트를 전달하기만 하면 되도록 변경되면서, Route의 prop과 사용자가 전달하는 prop을 동시에 받을 수 있다. (e.g. <Route element={<Signin prop={myprop} />}>)
withRouter도 쓸 필요가 없어진 게, param이나 location을 useParams, useLocation 등 RRD가 제공하는 훅을 통해 접근할 수 있다. useNavigate 또한 route match를 가져오는 훅으로 제공된다.
Route에서 지정해주지 않은 경로에 대해서 이전 버전에서는 Redirect라는 컴포넌트로 관리했지만 이제는 Route로 바로 관리하자.
6버전에서는 <Route path="*" element={<{RedirectComponent} />} />로 지정된 path 외의 모든 경로에 대해서 컴포넌트를 전달하면 처리된다.
또는 <Route path="*" element={<Navigate to="{다른 Route의 path 값}" replace="true" />} />로 redirect하는 경로를 넣어주면 미리 준비된 다른 route로 안내한다.
이 때 replace 값은 history에서 redirect 전의 invalid page를 빼준다. (현재의 준비된 redirect path로 대체)
Navigate 전의 특정 값을 담아 넘겨줄 수 있는 state prop도 있다.
// 지정되지 않은 경로 요청을 대응할 컴포넌트functionPageNotFound(props){console.log(props);return(<div><h2>페이지를 찾을 수 없습니다.</h2><Linkto="/">홈페이지</Link>로 이동
</div>);}exportdefaultfunctionApp(){return(<BrowserRouter><Routes><Routepath="page-not-found"element={<PageNotFound/>}/><Routepath="*"element={<Navigateto="page-not-found"replace={true}/>}/></Routes><BrowserRouter>
RRD에서는 HashRouter보다는 BrowserRouter를 쓸 것을 권장하고 있다.
BrowserRouter는 history API를 사용하므로 구형 브라우저에서는 지원되지 않는다는 점을 유의할 것
NavLink
내가 현재 머물고 있는 경로의 NavLink에는 active라는 활성클래스가 기본으로 제공되는데, 이 활성클래스 이름을 바꿀 수 있다.
원래는 isActive라는 상태를 받아 style이나 className에 함수로 ({isActive}) => isActive ? 'customActiveClassName':'' 등으로 처리해줄 수 있다.
하지만 우리는 styled Component를 쓰는데, styled component가 먼저 실행되면서 이 className에 작업하기 때문에 위의 함수가 의도한 대로 실행되지 않고 함수코드가 그대로 문자열로 클래스가 되어 html에 들어간다.
styled component를 사용할 때 활성 클래스 이름을 커스터마이징 하려면 RRD v5만이 제공하는 activeClassName을 통해 변경하고, styled Component에서 받는 클래스네임을 처리해주는 HOC를 만들어 NavLink를 래핑해주어야만 한다.
useHref, useClickHandler를 사용하여 나만의 NavLink도 만들 수 있다.
Outlet
Layout과 같이 모든 페이지에서 중복된 컴포넌트는 outer route로 감싸서 처리해줄 수 있다.
그러나 이 때 outer route component로 지정된 컴포넌트 안에 Outlet 컴포넌트를 넣어주어야 children route를 렌더링해준다.
// App.js 또는 outer Route를 렌더링 하는 곳exportdefaultfunctionApp(){return(<Router><Routes><Routeelement={<Layout/>}><Routepath="/"element={<Home/>}/><Routepath="signin"element={<SignIn/>}/>
// ... 이런 식으로 다른 Layout 속에 들어갈 자식요소들은 Outlet으로 끼워줘야만 렌더링된다.
</Route></Routes></Router>);}// Layout.js before exportfunctionLayout({children}){return(<Container><Header/><Wrapperas="main">{children}</Wrapper></Container>);}// Layout.js afterimport{Outlet}from'react-router-dom';exportfunctionLayout(){return(<Container><Header/><Wrapperas="main"><Outlet/></Wrapper></Container>);}
React Form
React가 제어하는 controlled component로 form 요소들을 만들어주어야 dom script가 아닌 setState을 통한 form 요소 제어가 가능하다.
Controlled input component
input의 value 등 사용자 입력으로 인해 바뀌는 요소에는 state를 prop 값으로 주고(initial value를 빈문자열 등으로 주면 된다), onChange 이벤트에 setter함수를 걸어주어야 Controlled component로서 form 요소를 사용할 수 있다.
onChange에 핸들러를 등록하지 않고 value만 주면, readOnly가 되기 때문에 ReadOnly를 명시하거나 이벤트핸들러를 등록해주어야만 한다.