GDSC FE-Toy Project Study Plan
- 'React를 다루는 기술' Ch15, 16 공부 및 실습 진행
[Week 9] 1/13
- 발표자
- Ch15. Context API - 장아연
- Ch16. 리덕스 라이브러리 이해하기 - 장효신
✔ 전역 상태 관리 흐름 이해
- 여러 컴포넌트를 거쳐 props 사용 시 기존의 top->bottom 흐름으로 많은 컴포넌트 거치거나 데이터가 많아지는 경우 유지 보수성 낮아짐
- Context 만들어 한번에 원하는 값 받아옴
✔ Context API 사용법
1. 새로운 Context 생성
- createContext 함수를 사용해 Context 생성
- 파라미터로 해당 Context 기본 상태 지정
import {createContext} from "react";
const ColorContext=createContext({color:"black"}); //기본 상태 색상 : 검정
export default ColorContext;
2. Consumer 사용
- ColorBox 컴포넌트 만들어 ColorContext 안에 있는 색상 불러옴
- props가 아닌 ColorContext 안에 Consumer 컴포넌트 사용
- Render Props : Consumer 사이에 중괄호 열어 그 안에 함수 넣음
import React from 'react';
import ColorContext from '../contexts/color';
const ColorBox=()=>{
return (
<ColorContext.Consumer>
{value =>(
<div style={{width:"64px", height:"64px", background:value.color}}/>
)}
</ColorContext.Consumer>
);
};
export default ColorBox;
3. App에서 랜더링
import './App.css';
import ColorBox from './component/ColorBox';
const App=()=>{
return (
<div>
<ColorBox/>
</div>
);
};
export default App;
4. Provider 사용
- Provider 사용해 Context의 value 변경
- Provider 사용하고 value 명시 안하면 오류 발생
import logo from './logo.svg';
import './App.css';
import ColorBox from './component/ColorBox';
import ColorContext from './contexts/color';
const App=()=>{
return (
<ColorContext.Provider value={{color:"red"}}>
{/*provider를 사용한 value 변경*/}
<div>
<ColorBox/>
</div>
</ColorContext.Provider>
);
};
export default App;
✔ 동적 Context 사용
1. 함수 전달하는 Context
- 새로 작성한 ColorProvider 컴포넌트에 ColorContext.Provider 랜더링
- Provider의 value에 상태(state), 업데이트 함수(actions) 분리해서 묶어서 전달하면 다른 컴포넌트에 Context 값 사용할 때 편함
import {createContext, useState} from "react";
const ColorContext=createContext({
state:{color:"black", subcolor:"red"},
actions:{
setColor:()=>{},
setSubcolor:()=>{}
}
});
const ColortProvider=({children})=>{
const [color,setColor]=useState("black");
const [subcolor,setSubcolor]=useState("red");
const value={
state:{color,subcolor}, //상태
actions:{setColor,setSubcolor} //업데이트 함수
};
return (
//상태와 업데이트 함수 따로 분리하여 작성하여
//ColorContext.Provider에 넣는 객체의 형태와 일치 하는 것이 좋음
<ColorContext.Provider value={value}>
{children}
</ColorContext.Provider>);
};
//const ColorConsumer =ColortContext.Consumer
const {Consumer:ColorConsumer}=ColorContext;
//ColorProvider와 ColorConsumer 내보내기
export {ColortProvider,ColorConsumer};
export default ColorContext;
2. 새로운 Context 프로젝트 반영
- App 컴포넌트에서 ColorContext.Provider -> ColorProvider
import './App.css';
import ColorBox from './component/ColorBox';
import { ColortProvider } from './contexts/color';
const App=()=>{
return (
<ColortProvider>
<div>
<ColorBox/>
</div>
</ColortProvider>
);
};
export default App;
- ColorBox 컴포넌트에서 ColorContext.Consumer -> ColorConsumer
- 객체 비구조화 할당 문법 사용해 value.state.color -> state.color
import React from 'react';
import { ColorConsumer } from '../contexts/color';
const ColorBox=()=>{
return (
<ColorConsumer>
{({state})=>(
<>
<div
style={{width:"64px", height:"64px",background:state.color}}/>
<div
style={{width:"32px", height:"32px", background:state.subcolor}}/>
</>
)
}
</ColorConsumer>
);
};
export default ColorBox;
3. 컬러 선택 팔레트 UI
import React from 'react';
const colors=["red","orange","yellow","green","blue","indigo","violet"];
const SelectColors=()=>{
return (
<div>
<h2> 색상을 선택하세요.</h2>
<div style={{display:"flex"}}>
{colors.map(color=>(
<div key={color}
style={{
background:color,
width:"24px",
height:"24px",
cursor:"pointer"
}}/>
))}
</div>
<hr/>
</div>
);
};
export default SelectColors;
import './App.css';
import ColorBox from './component/ColorBox';
import { ColortProvider } from './contexts/color';
import SelectColors from './component/SelectColors';
const App=()=>{
return (
<ColortProvider>
<div>
<SelectColors/>
<ColorBox/>
</div>
</ColortProvider>
);
};
export default App;
4. 컬러 팔레트 클릭으로 색상 변경
- 마우스 왼쪽 클릭 : 큰 정사각형 색상 변경
- 마우스 오른쪽 클릭 : 작은 정사각형 색상 변경
import React from 'react';
import { ColorConsumer } from '../contexts/color';
const colors=["red","orange","yellow","green","blue","indigo","violet"];
const SelectColors=()=>{
return (
<div>
<h2> 색상을 선택하세요.</h2>
<ColorConsumer>
{({actions})=>(
<div style={{display:"flex"}}>
{colors.map(color=>(
<div
key={color}
style={{background:color,width:"24px", height:"24px",cursor:"pointer"}}
//마우스 왼쪽 클릭 : 큰 정사각형 색상 변경
onClick={()=>actions.setColor(color)}
//마우스 오른쪽 클릭 : 작은 정사각형 색상 변경
onContextMenu={e=>{
e.preventDefault();
//마우스 오른쪽 버튼 클릭 시 메뉴가 뜨는 것을 무시
actions.setSubcolor(color);
}}
/>
))}
</div>
)}
</ColorConsumer>
<hr/>
</div>
);
};
export default SelectColors;
Ch 16. 리덕스 라이브러리 이해하기
1) 리덕스란?
npm trends 최근 1년간 다운로드 수
- 가장 많이 사용하는 리엑트 상태 관리 라이브러리
- 그 외 MobX, Recoil, Context API, useSWR, react-query, apollo
- 컴포넌트의 상태 관련 업데이트 로직을 다른 파일로 분리시켜서 효율적으로 관리할 수 있음
- 컴포넌트에서 똑같은 상태를 공유해야 할 때, 여러 컴포넌트를 거치지 않고 상태 값을 전달/업데이트할 수 있음
- 단순히 전역 상태관리만 한다면 Context API를 사용하는 것만으로도 충분하지만, 리덕스를 사용하면 상태를 더욱 체계적으로 관리할 수 있기 때문에 프로젝트 규모가 클 경우 리덕스 사용 추천
- 장점
- 코드의 유지 보수성 높여줌
- 작업 효율 극대화 해줌
- 개발자 도구 지원 (Redux DevTools)
- 미들웨어 기능 제공(Redux-thunk, Redux-saga). 비동기 작업을 효율적으로 관리할 수 있음
2) 리덕스 개념 정리
리덕스를 사용하면서 만나게 될 키워드 5가지
- 액션
- 스토어
- 디스패치
- 리듀서
- 구독
액션
액션은 상태 변화를 일으킬 때 참조하는 객체로 상태에 어떤 변화가 필요할 때 액션 발생함
형식
하나의 객체로 표현됨
{
type: 'TOGGLE_VALUE', // 반드시 있어야 함
data: { // 마음대로 넣을 수 있음
id: 1,
text: '리덕스 배우기'
}
}
이 액션 객체는 반드시 type 필드를 가지고 있어야 함
type의 값은 액션의 이름
그 외의 값은 나중에 상태를 업데이트할 때 참고해야 할 값으로 마음대로 넣을 수 있음
액션 생성 함수
액션 객체를 만들어주는 함수
function addTodo(data){
return {
type: 'ADD_TODO',
data
};
}
// 화살표 함수로도 만들 수 있음 (추천)
const changeInput = text => ({
type: 'CHANGE_INPUT',
text
});
사용 목적
- 변화를 일으킬 때마다 액션 객체를 만들어야 하는데 매번 액션 객체를 작성하기는 번거롭고 만드는 과정에서 실수할 수 있음
- 이러한 일을 방지하기 위해 함수로 만들어서 관리함
리듀서
리듀서는 실제로 변화를 일으키는 함수
순서
1. 액션을 만들어서 발생시킴
2. 리듀서가 현재 상태와 전달 받은 액션 객체를 파라미터로 받아옴
3. 두 값을 참고해서 새로운 상태 반환
const initialState = {
counter: 1
};
// state값이 undefined면 initialState를 참조함
function reducer(state=initialState, action) {
switch(action.type){
case INCREMENT:
return {
counter: state.counter + 1 // state와 action 객체를 참조해서 새로운 state를 반환함
};
default:
return state;
}
}
스토어
한 개의 프로젝트는 한 개의 스토어만 가짐
스토어 안에 현재 애플리케이션 상태와 리듀서가 들어가 있음
디스패치
dispatch
스토어의 내장 함수 중 하나로 액션을 발생시키는 것
순서
1. dispatch(action)처럼 액션 객체를 파라미터로 전달해서 호출함
2. 리듀서 함수 실행시켜서 새로운 상태 반환
구독
subscribe
스토어의 내장 함수 중 하나
용례
subscribe 함수 안에 리스너 함수를 넣어서 호출하면
액션이 디스패치 되어 상태가 업데이트될 때마다 리스너 함수가 호출됨
const listener = () => {
console.log('상태가 업데이트됨');
}
const unsubscribe = store.subscribe(listener);
unsubscribe(); // 구독을 비활성화할 때 함수를 호출
구독 비활성화할때는 unsubscribe() 함수 호출함
'3-1기 스터디 > Front-End 토이 프로젝트' 카테고리의 다른 글
[8주차] 외부 API 연동 news viewer 제작 (0) | 2022.01.30 |
---|---|
[10주차] 리덕스 미들웨어를 통한 비동기 작업 관리 (0) | 2022.01.30 |
[7주차] immer를 사용해 쉽게 불변성 유지하기 (0) | 2022.01.07 |
[6주차] 컴포넌트 반복, 라이프사이클 메서드, 함수형 컴포넌트 (0) | 2021.12.22 |
[5주차] 이벤트 핸들링, ref: DOM에 이름 달기 (0) | 2021.11.25 |
댓글