6.1 별점 컴포넌트 만들기
- react-icons (npm 라이브러리)
6.2 useState 훅
- 훅스에는 컴포넌트 트리와는 별도로 재사용 가능한 코드 로직이 들어있음
- useState 훅: 상태를 리액트 컴포넌트에 추가하고 싶을 때 사용
- React 패키지에 들어있음
- 배열 반환
- 배열의 첫 번째 값은 상태 변수
- 배열의 두 번째 값은 상태 값을 변경할 때 쓸 수 있는 함수
- useState 함수에 전달하는 값은 상태 변수의 default 값
- 훅이 걸린 데이터가 변경되면 데이터에 대한 훅이 걸린 컴포넌트에 새 값을 전달하면서
컴포넌트 re-rendering 일어남
6.3 재사용성을 높이기 위한 리팩터링
- style 프로퍼티; CSS 스타일을 엘리먼트에 추가 가능
- JSX에서 이중 중괄호 이용
6.4 컴포넌트 트리 안의 상태
- 상태를 컴포넌트 트리의 아래로 내려보내기
- 루트 App 컴포넌트에만 상태 저장해서 자식 컴포넌트들에게 프롭으로 전달
- 순수 컴포넌트; 상태가 없어서 항상 같은 프롭에 대해 같은 UI를 렌더링 해주는 컴포넌트
- 상호작용을 컴포넌트 트리 위쪽으로 전달하기
- 자식 컴포넌트에 대해 벌어진 상호작용을 수집해서 트리의 위로 올려보내어 상태가 저장된 루트에 도착
- 요소 제거하고 싶을 때 filter 함수 이용
- 프롭을 통해 데이터를 컴포넌트 트리로 내려보내는 것과 비슷하게,
사용자 상호작용은 함수 프로퍼티를 통해 데이터와 함께 트리 위로 전달됨
6.5 폼 만들기
- 참조 사용하기
- 폼 컴포넌트; ref라는 리액트 기능을 사용해 직접 DOM에 접근 가능
- ref; 리액트에서 컴포넌트의 생명주기 값을 저장하는 객체
- useRef 훅
- input 엘리먼트에 ref 속성 추가
- DOM 엘리먼트를 직접 참조하는 ref 객체에 대한 current 필드 생성
- 리액트 밖에서 폼에 접근해 폼에 속한 입력 값 처리하고 싶을 때 사용
- uncontrolled 컴포넌트, 명령형 코드
import React, { useRef } from 'react';
export default function AddColorForm({ onNewColor = (f) => f }) {
const txtTitle = useRef();
const hexColor = useRef();
const submit = (e) => {
e.preventDefault();
const title = txtTitle.current.value;
const color = hexColor.current.value;
onNewColor(title, color);
txtTitle.current.value = '';
hexColor.current.value = '';
};
return (
<form onSubmit={submit}>
<input ref={txtTitle} type="text" placeholder="color title..." required />
<input ref={hexColor} type="color" required />
<button>ADD</button>
</form>
);
}
- 제어가 되는 컴포넌트
- controlled 컴포넌트에서는 폼 값을 DOM이 아니라 리액트로 관리함
- useRef 사용할 필요 없음, 명령형 코드 작성할 필요 없음
- useRef 대신 useState 이용
import React, { useState } from 'react';
export default function AddColorForm({ onNewColor = (f) => f }) {
const [title, setTitle] = useState('');
const [color, setColor] = useState('#000000');
const submit = (e) => {
e.preventDefault();
onNewColor(title, color);
setTitle('');
setColor('');
};
return (
<form onSubmit={submit}>
<input
value={title}
onChange={(event) => setTitle(event.target.value)}
type="text"
placeholder="color title..."
required
/>
<input
value={color}
onChange={(event) => setColor(event.target.value)}
type="color"
required
/>
<button>ADD</button>
</form>
);
}
- 커스텀 훅 만들기
import { useState } from 'react';
export const useInput = (initialValue) => {
const [value, setValue] = useState(initialValue);
return [
{ value, onChange: (e) => setValue(e.target.value) },
() => setValue(initialValue),
];
};
import React, { useState } from 'react';
import { useInput } from '../hooks/useInput';
export default function AddColorForm({ onNewColor = (f) => f }) {
const [titleProps, resetTitle] = useInput('');
const [colorProps, resetColor] = useInput('#000000');
const submit = (e) => {
e.preventDefault();
onNewColor(titleProps.value, colorProps.value);
resetTitle('');
resetColor('');
};
return (
<form onSubmit={submit}>
<input
{...titleProps}
type="text"
placeholder="color title..."
required
/>
<input {...colorProps} type="color" required />
<button>ADD</button>
</form>
);
}
- 색을 상태에 추가하기
import React, { useState } from 'react';
import colorData from './data/color-data';
import ColorList from './components/ColorList';
import AddColorForm from './components/AddColorForm';
import { v4 } from 'uuid';
function App() {
const [colors, setColors] = useState(colorData);
return (
<>
<AddColorForm
onNewColor={(title, color) => {
const newColors = [
...colors,
{
id: v4(),
rating: 0,
title,
color,
},
];
setColors(newColors);
}}
/>
<ColorList
colors={colors}
onRemoveColor={(id) => {
const newColors = colors.filter((color) => color.id !== id);
setColors(newColors);
}}
onRateColor={(id, rating) => {
const newColors = colors.map((color) =>
color.id === id ? { ...color, rating } : color
);
setColors(newColors);
}}
/>
</>
);
}
export default App;
6.6 리액트 콘텍스트
- 콘텍스트에 색 넣기
- Context Provider에게 데이터를 넣고, Provider를 컴포넌트 트리에 추가
- createContext 함수를 이용하여 새로운 Context 객체 생성
- Context 객체에는 Context Provider와 Context Consumer 2가지 컴포넌트가 들어 있음
- useContext를 통해 색 얻기
- 상태가 있는 콘텍스트 프로바이더
- Context Provider는 객체를 Context에 넣을 수 있음
- Context Provider 자체로는 Context 상에 들어 있는 값 변경 불가
- Context Provider를 렌더링하는 상태가 있는 컴포넌트로 만들기 => Custom Provider
import React, { createContext, useState } from 'react';
import colorData from './data/color-data';
import { v4 } from 'uuid';
const ColorContext = createContext();
export default function ColorProvider({ children }) {
const [colors, setColors] = useState(colorData);
const addColor = (title, color) => {
setColors([
...colors,
{
id: v4(),
rating: 0,
title,
color,
},
]);
};
const removeColor = (id) =>
setColors(colors.filter((color) => color.id !== id));
const rateColor = (id, rating) =>
setColors(
colors.map((color) => (color.id === id ? { ...color, rating } : color))
);
return (
<ColorContext.Provider value={{ colors, addColor, removeColor, rateColor }}>
{children}
</ColorContext.Provider>
);
}
- 콘텍스트와 커스텀 훅
const ColorContext = createContext();
export const useColors = () => useContext(ColorContext);
'Books > 러닝 리액트 ✔️' 카테고리의 다른 글
[Learning React] 8장 - 데이터 포함시키기 (0) | 2022.02.01 |
---|---|
[Learning React] 7장 - 훅스로 컴포넌트 개선하기 (0) | 2022.02.01 |
[Learning React] 5장 - JSX를 사용하는 리액트 (0) | 2022.01.31 |
[Learning React] 4장 - 리액트의 작동 원리 (0) | 2022.01.31 |
[Learning React] 3장 - 자바스크립트를 활용한 함수형 프로그래밍 (0) | 2022.01.30 |
댓글