2023.04.05 메타코딩(유튜브)들으면서 정리한 추가 리액트 문법
useEffect()사용할때
useEffect(() => { } , [ ])
빈배열을 넣으면 App( )이 실행될때 최초 1번만 실행된다.
[arr]을 넣으면 arr의 값이 변할때마다 실행된다.
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으로 넘긴뒤.
화면에 표시하고 버튼 클릭시 숫자 증가하게 만들기.
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;
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;
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>
);
};
부모 컴포넌트로부터 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 상속받아 추가하기.
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, useHistory 대신 useNavigate로 교체
v5에서 사용하던 history객체는 라우트로 사용된 컴포넌트에게 match, location 과 함께 사용이 가능했다.
앞으로 v6부터 useHistory는 아예 사라졌고, history도 기존에 선언하는 방식처럼 선언하면 안된다
"useNavigate를 사용해야 한다"
App 컴포넌트를 BrowserRouter로 감싸기
<BrowserRouter>
<App />
</BrowserRouter>
exact={true} 는 주소를 정확히 읽으라는 뜻이다.
'/'가 메인페이지 이기 때문에 exact={true}가 필요.
만약 path='/'가 없으면 exact={true} 필요 없다.
ex) 아래처럼 주소가 다 다를때는 exact={true} 필요 없다.
path='/home'
path='/login'
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>
);
}
라이브러리 다 설치해도 안될때 !!
vs code 1.77 버전이랑 충돌이 난다고한다!!!
1.76버전으로 다시 다운로드 후 설정-update에서
Update:Mode를 none으로 변경하자!!

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를 유지하되 변경된 부분을 추가하는 방식으로 진행해야한다!!!!
객체의 key값을 표현식(변수, 함수 등)을 통해 지정하는 문법
let key = "name";
let obj = {
[key] : "yujuck"
}
// obj = { name: "yujuck" }