TIL 23-11-14

thisisyjin·2023년 11월 14일
0

TIL 📝

목록 보기
96/113

React.js

React-router-dom

  • 리액트는 SPA이기 때문에 하나의 index 파일을 갖는데, Js를 이용해서 다른 컴포넌트를 넣어서 페이지를 변경하도록 해줌
  • 이때 라우터 역할을 해주는 것이 바로 react-router-dom임.

React Router 설정

index.js

ReactDom.render(
  <BrowserRouter>
  	<App />
 </BrowserRouter>, document.getElementById('root'))

여러 컴포넌트 생성 및 라우트 정의

  • Routes > Route 와 같은 구조로 생성
<Routes>
  <Route path="/" element={<HomePage />} />
</Routes>

Link를 통한 경로 이동

  • anchor 태그이지만, 페이지 로딩 없이 이동 가능
<Link to="/about">About</Link>

중첩 라우팅 (Nested Routes)

  • 공통 부분 (레이아웃) 코드를 보여줄 수 있음
<Routes>
	<Route path="/" element={<App />} />
  		<Route index element={<Home />} />
  		<Route path="teams" element={<Teams/>} />
  			<Route path=":teamId" element={<Team />} />
</Routes>

Outlet

  • 자식 경로 요소를 렌더링하기 위해 부모 경로 요소에서 Outlet 사용
  • 예> '/' 경로에서 하위 경로인 '/teams'를 사용하기 위해서 사용

useNavigate

const navigate = useNavigate();
navigate('/home');

useParams

  • URL Params 값을 가져올 수 있음

useLocation

  • 현재 위치 객체 반환

useRoutes

  • Routes 컴포넌트 생성

Projects

/pages 폴더 구조

  • 강의에서는 아래와 같이 페이지별 폴더 생성하고, Index.jsx 생성함
    /src/pages/DetailPage/index.jsx
    /src/pages/MainPage/index.jsx

  • 나는 기존에 /src/pages/PageName.jsx 와 같이 직접 생성했었음

데이터 가공

  • 배열 구조분해 할당 이용
const formatStats = ([
  statHp,
  statATK,
  statDEP,
  statSATK,
  statSDEP,
  statSPD
]) => [
  {name: 'Hit Points', baseStat: statHp.base_stat},
  {name: 'Attack', baseStat: statATK.base_stat},
  {name: 'Defence', baseStat: statDEP.base_stat},
  {name: 'Special Attack', baseStat: statSATK.base_stat},
  {name: 'Special Defence', baseStat: statSDEP.base_stat},
  {name: 'Speed', baseStat: statSPD.base_stat}
]

await Promise.all()

  • Promise.all()안에 있는 비동기 작업들 다 처리 후, 한꺼번에 Return
const DamageRelations = awiat Promise.all(
  types.map(async (i) => {
    const type = await axios.get(i.type.url);
    return type.data.damage_relations
  })
)

Loading

=const [isLoading, setIsLoading] = useState(false);

useEffect(() => {
  setIsLoading(true);
  fetchPokemonData(params.id);
}, [params]);

결과가 없는 경우 (Not Found)

  • Try-catch에서 catch문에도 setIsLoading(false)를 해줘야 함
{(!isLoading && !pokemon) && (
    <div>Not Found</div>
)}

useRef

✅ 참고

  • useEffect에서 deps 배열이 없다면 어떤 state든 변경될 때 실행된다!
  1. 렌더링 수 기록하기
  • renderCount
const [value, setValue] = useState("");
const renderCountRef = useRef(0);

useEffect(() => {
  renderCountRef.current++;
})

forwardRef

  • DOM 요소 선택
  • 포커스 주기 등
const inputRef = useRef();

const handleClick = () => {
  inputRef.current.focue();
}

...
return (
   <input ref={inputRef} />
)
  • 단, 자식 컴포넌트에 ref를 사용할 수 없음 (ref는 props로 사용 불가하기 때문)
  • 이때 사용하는 것이 바로 forwardRef!
const ChildComponent = (props, ref) => {
  return <input ref={ref}/>
}

export default forwardRef(ChildComponent);
  • 인자 두개 가져옴 (props, ref)
  • 주의: props 안에 ref가 있을 수는 없다.
  • 더 간단한 해결 방법은 ref라는 이름 말고 InputRef 등의 이름으로 내려주면 끝.
profile
기억은 한계가 있지만, 기록은 한계가 없다.

0개의 댓글