추가 리액트 문법

정원·2023년 4월 5일

React+Spring

목록 보기
4/8

2023.04.05 메타코딩(유튜브)들으면서 정리한 추가 리액트 문법

useEffet()

useEffect()사용할때
useEffect(() => { } , [ ])
빈배열을 넣으면 App( )이 실행될때 최초 1번만 실행된다.

[arr]을 넣으면 arr의 값이 변할때마다 실행된다.

props

props로 넘겨주는 값은 꼭 상태값이어야한다.

const [list, setList] = useState({id:1, title:"제목", content:"내용"});
const list2 = {id:1, title:"제목", content:"내용"} // 이걸 넘겨주면 렌더링이 발생하지 않기 때문에 데이터 전달이 안됨!!!
...
<Home list={list} setList={setList} />

props로 list와 setList를 전달해주면
자식 컴포넌트에서 이 두개를 사용할 수 있다.

const Home = (props) => {
  	 // 구조분할 할당
 	 const {list, setList} = props;
  {list.map((list)=> 
        <h3>
            {list.title}
            {list.content}
  		</h3>
	)}
	<button onClick={() => setList([])}>전체삭제</button>
}

예제

HomePage에서 data를 가지고 있고
props로 Home으로 넘긴뒤.
화면에 표시하고 버튼 클릭시 숫자 증가하게 만들기.

HomPage

import React from 'react';
import { useState } from 'react';
import Home from './Home';

const HomePage = () => {
  const [num, setNum] = useState(0);
  return (
    <div>
      <Home num={num} setNum={setNum} />
    </div>
  );
};

export default HomePage;

Home

import React from 'react';

const Home = (props) => {
  const { num, setNum } = props;
  return (
    <div>
      <h1>{num}</h1>
      <button onClick={() => setNum(num + 1)}>더하기</button>
    </div>
  );
};

export default Home;

styled-components props

HomPage

const HomePage = () => {
  const [num, setNum] = useState(0);
  const [user, setUser] = useState([]);

  useEffect(() => {
    setUser({ id: 1, username: 'kim' });
  }, []);
  return (
    <div>
      <Home num={num} setNum={setNum} user={user} />
    </div>
  );
};

Home

부모 컴포넌트로부터 user 값을 받아오고
스타일 컴포넌트에 user값을 전달.
스타일 컴포넌트에서는 props.user로
원하는 조건식에 따른 스타일 적용.

const StyledDeleteButton = styled.button`
  color: ${(props) => (props.user.username === 'kim' ? 'blue' : 'red')};
`;

const Home = (props) => {
  const { num, setNum, user } = props;
  return (
    <div>
      <StyledDeleteButton user={user}>삭제</StyledDeleteButton>
    </div>
  );
};

styled-components 상속

재사용 원하는 styled-components 상속받아 추가하기.

const StyledDeleteButton = styled.button`
  color: ${(props) => (props.user.username === 'kim' ? 'blue' : 'red')};
`;
const StyledAddButton = styled(StyledDeleteButton)`
  background-color: green;
`;

리액트는 a태그를 사용할 수 없다.
a태그는 무조건 새로고침이 되기때문에
리액트에서 사용하는 것이 부적절하다.

그렇기 때문에 react-router-dom에서 제공하는 Link를 사용한다.

<Link to="/"></Link>
<Link to="/login"></Link>

styled-components에서는 Link가 없기 때문에
상속받아서 사용하면 된다.

import { Link } from 'react-router-dom';
...
const StyledLink = styled(Link)`
	...
`;

history

history, useHistory 대신 useNavigate로 교체

v5에서 사용하던 history객체는 라우트로 사용된 컴포넌트에게 match, location 과 함께 사용이 가능했다.

앞으로 v6부터 useHistory는 아예 사라졌고, history도 기존에 선언하는 방식처럼 선언하면 안된다

"useNavigate를 사용해야 한다"

라우팅하기

react-router-dom 인스톨

index.js

App 컴포넌트를 BrowserRouter로 감싸기

<BrowserRouter>
    <App />
</BrowserRouter>

App.js

exact={true} 는 주소를 정확히 읽으라는 뜻이다.
'/'가 메인페이지 이기 때문에 exact={true}가 필요.
만약 path='/'가 없으면 exact={true} 필요 없다.

ex) 아래처럼 주소가 다 다를때는 exact={true} 필요 없다.
path='/home'
path='/login'

Router 오류 (6.x.x 버전에서 바뀐 사용법)

Error: A <Route> is only ever to be used as the child of <Routes> element

Route 를 Routes 로 감싸기.

function App() {

  return (
    <div>
      <Header />
    <Routes>
      <Route path='/' exact={true} Component={HomePage} />
      <Route path='/login' exact={true} Component={LoginPage} />
        </Routes>
      <Footer />
    </div>
  );
}

styled-components 자동완성 안될때

라이브러리 다 설치해도 안될때 !!
vs code 1.77 버전이랑 충돌이 난다고한다!!!
1.76버전으로 다시 다운로드 후 설정-update에서
Update:Mode를 none으로 변경하자!!

form(input) 입력값 바꾸기

form태그를 쓸때는
input에 value를 상태값을 주고
onChange가 발생했을때 set값을 바꿔준다.

 const [post, setPost] = useState({
    id: '',
    title: '',
    content: '',
  });
...

  const handleChangeTitle = (e) => {
    setPost({ title: e.target.value });
  };

  const handleChangeContent = (e) => {
    setPost({ content: e.target.value });
  };

이렇게 할때마다 이벤트를 만들어줘야하기 때문에
이럴때는 각 input태그에 name을 추가하고 이를 이용하면 된다.

 const handleForm = (e) => {
    // computed property names 문법(키값 동적할당)
    setPost({ [e.target.name]: e.target.value });
  };
...
<input
  type="text"
  placeholder="제목을 입력하세요.."
  value={post.title}
  onChange={handleForm}
  name="title"
/>
<input
  type="text"
  placeholder="내용을 입력하세요.."
  value={post.content}
  onChange={handleForm}
  name="content"
/>

이렇게만하면 title이나 content 둘중하나만 수정이된다.
왜그럴까...????

title이 수정된후에 기존에 아무것도 없던 곳에
title이 들어가고
content가 수정된후에도 기존에 아무것도 없던 곳에
content가 들어간다!!
계속 초기화가 되기 때문에!!!

const handleForm = (e) => {
    setPost({ ...post, [e.target.name]: e.target.value });
  };

기존 post를 유지하되 변경된 부분을 추가하는 방식으로 진행해야한다!!!!

Computed Property Name

객체의 key값을 표현식(변수, 함수 등)을 통해 지정하는 문법

let key = "name";
let obj = {
  [key] : "yujuck"
}

// obj = { name: "yujuck" }

0개의 댓글