1. 리액트가 만들어진 계기
어떠한 상태가 바뀌었을때, 그 상태에 따라 DOM 을 어떻게 업데이트 할 지 규칙을 정하면 코드가 복잡해지는 문제가 있다.
리액트는 상태가 업데이트 되면, 업데이트가 필요한 곳의 UI 를 Virtual DOM 을 통해서 렌더링하고 실제 브라우저에 보여지고 있는 DOM 과 비교를 한 후, 차이가 있는 곳을 감지하여 이를 실제 DOM 에 패치시키는 방법으로 이 문제를 해결하였다.
2. 새 프로젝트 만들기
터미널에서 다음 명령어를 실행한다.
$ npx create-react-app begin-react #(프로젝트명)
해당 디렉터리에 들어간 다음 명령어를 실행한다.
$ yarn start # 혹은 npm start
3. 리액트 컴포넌트 만들기
리액트 컴포넌트를 만들 때에는 다음 코드가 필요하다.
import React from 'react';
컴포넌트를 내보낼 때에는 코드의 최하단에 다음 코드를 작성한다. 이렇게 하면 다른 컴포넌트에서 사용할 수 있게 된다.
export default Hello; # Hello는 컴포넌트 이름이다.
이렇게 만든 컴포넌트는 다음과 같은 방법으로 사용할 수 있으며, 재사용이 가능하다.
<Hello />
4. JSX의 기본 규칙
- 태그는 꼭 닫혀있어야 한다.
- 두 개 이상의 태그는 무조건 하나의 태그로 감싸져있어야 한다. 이 때 꼭 div 태그가 아니어도 되며, Fragment(<></>) 로 감싸주 어도 된다.
- JSX 내부에 자바스크립트 변수를 보여줘야 할 때에는 {} 으로 감싸서 보여준다.
- style을 설정할 때 인라인 스타일은 객체 형태로 작성을 해야 하며, background-color 처럼 - 로 구분되어 있는 이름들은 backgroundColor 처럼 camelCase 형태로 네이밍 해주어야 한다.
- CSS class 를 설정 할 때에는 class= 가 아닌 className= 으로 설정을 해주어야 한다.
- JSX 내부의 주석은 {/* 이런 형태로 */} 작성해야하며, 열리는 태그 내에서는 // 이런 형태로 작성할 수도 있다.
5. props
props 는 properties 의 줄임말이며 우리가 어떠한 값을 컴포넌트에게 전달해줘야 할 때 사용한다.
Hello 컴포넌트에 name 이라는 값을 전달하고 싶다면 다음과 같이 사용하면 된다.
#App.js
import React from 'react';
import Hello from './Hello';
function App() {
return (
<Hello name="react" color="red"/>
);
}
export default App;
#Hello.js
import React from 'react';
function Hello(props) {
return <div style={{ color: props.color }}>안녕하세요 {props.name}</div>
}
export default Hello;
이 때 함수의 파라미터에서 비구조화 할당(혹은 구조 분해) 문법을 사용하면 조금 더 코드를 간결하게 작성 할 수 있다.
컴포넌트에 props 를 지정하지 않았을 때 기본적으로 사용 할 값을 설정하고 싶다면 컴포넌트에 defaultProps 라는 값을 설정하면 됩니다.
function Hello({ color, name }) {
return <div style={{ color }}>안녕하세요 {name}</div>
}
Hello.defaultProps = {
name: '이름없음'
}
컴포넌트 태그 사이에 넣은 값을 조회하고 싶을 때에는 props.children을 사용한다.
다음 코드에서는 children을 사용하면 <Wrapper></Wrapper> 사이의 값을 사용할 수 있다.
# Wrapper.js
import React from 'react';
function Wrapper({ children }) {
const style = {
border: '2px solid black',
padding: '16px',
};
return (
<div style={style}>
{children}
</div>
)
}
export default Wrapper;
<Wrapper>
<Hello name="react" color="red"/>
<Hello color="pink"/>
</Wrapper>
6. 조건부 렌더링
다음 코드들은 isSpecial 값이 true일 때 <b>*</b> 를 보여준다.
{ isSpecial ? <b>*</b> : null }
{isSpecial && <b>*</b>}
다음 코드와 같이 props을 사용할 때 props 이름만 작성하면 자동으로 true로 설정된다.
<Hello name="react" color="red" isSpecial />
7. useState
useState를 이용하여 컴포넌트에서 상태를 관리 할 수 있다.
useState 정의 방법
const [number, setNumber] = useState(0);
다음 방법을 통해 number 값을 바꿀 수 있다.
setNumber(number + 1);
setNumber(prevNumber => prevNumber + 1);
8. input 상태 관리
다음 방법을 통해 input 상태 관리를 할 수 있다.
const [text, setText] = useState('');
const onChange = (e) => {
setText(e.target.value);
};
const onReset = () => {
setText('');
};
input 태그의 value 값을 설정해주어 input 입력값이 바뀌었을 때 업데이트를 할 수 있다.
<input onChange={onChange} value={text} />
<button onClick={onReset}>초기화</button>
여러개의 input을 관리할 때에는 객체 형태를 사용하는 것이 좋다.
const [inputs, setInputs] = useState({
name: '',
nickname: ''
});
<input name="name" placeholder="이름" onChange={onChange} value={name} />
<input name="nickname" placeholder="닉네임" onChange={onChange} value={nickname}/>
setInputs({
...inputs, // 기존의 input 객체를 복사한 뒤
[name]: value // name 키를 가진 값을 value 로 설정
});
9. useRef
1. 특정 DOM 선택
useRef를 사용하여 특정 DOM을 선택할 수 있다.
다음 방법으로 onReset 함수 실행시 이름 input에 focus를 할 수 있다.
const nameInput = useRef();
const onReset = () => {
setInputs({
name: '',
nickname: ''
});
nameInput.current.focus();
};
<input
name="name"
onChange={onChange}
value={name}
ref={nameInput}
/>
2. 컴포넌트 안 변수 만들기
useRef 로 관리하는 변수는 값이 바뀐다고 해서 컴포넌트가 리렌더링되지 않는다.
리액트 컴포넌트에서의 상태는 상태를 바꾸는 함수를 호출하고 나서 그 다음 렌더링 이후로 업데이트 된 상태를 조회 할 수 있는 반면, useRef 로 관리하고 있는 변수는 설정 후 바로 조회 할 수 있다.
const nextId = useRef(4);
const onCreate = () => {
// 배열에 항목 추가하는 로직
nextId.current += 1;
};
이 값을 수정 할때에는 .current 값을 수정하면 되고 조회 할 때에는 .current 를 조회하면 된다.
10. 배열 렌더링
map() 함수를 이용하여 배열을 간단한 방법으로 렌더링할 수 있다.
<div>
{users.map((user, index) => (
<User user={user} key={index} />
))}
</div>
배열을 렌더링할 때는 고유한 key값이 있어야 한다.
11. 배열
1. 항목 추가
const [users, setUsers] = useState([
{
id: 1,
username: 'velopert',
email: 'public.velopert@gmail.com'
},
]);
방법1) spread 이용
const user = {
id: nextId.current,
username,
email
};
setUsers([...users, user]);
방법2) concat 이용
setUsers(users.concat(user));
2. 항목 제거
const onRemove = id => {
// user.id 가 파라미터로 일치하지 않는 원소만 추출해서 새로운 배열을 만듬
// = user.id 가 id 인 것을 제거함
setUsers(users.filter(user => user.id !== id));
};
3. 항목 수정
const [users, setUsers] = useState([
{
id: 1,
username: 'velopert',
email: 'public.velopert@gmail.com',
active: true
}
]);
const onToggle = id => {
setUsers(
users.map(user =>
user.id === id ? { ...user, active: !user.active } : user
)
);
};
배열의 불변성을 유지하면서 배열을 업데이트 할 때에 map 함수를 사용 할 수 있다.
'WINK-(Web & App) > React.js 스터디' 카테고리의 다른 글
[2024-2 React.js 스터디] 김지수 #2주차 (0) | 2024.10.30 |
---|---|
[2024-2 React.js 스터디] 이서영 #1주차 (0) | 2024.10.10 |
[2024-2 React.js 스터디] 김지수 #1주차 (5) | 2024.10.08 |
[2024 여름방학 React.js 스터디] 이종윤 #6주차 (0) | 2024.08.19 |
[2024 여름방학 React.js 스터디] #6주차 이가인 (0) | 2024.08.16 |