⚛️ 기본 환경: IDE: VS code, Language: React

 

 

발생 Error

React에서 다음 Source Code를 실행할 경우,

1
2
import { createSlice } from "@reduxjs/toolkit";
 
 
 

🚨 다음과 같은 경고 발생

"reduxjs": Unknown word.cSpell

 

 

발생 원인

VS Code 확장자 중 'Code Spell Checker'에서 reduxjs를 오타로 인식

 

 

해결 방법

Quick fix → Add "reduxjs" to workspace settings → (자동) .vscode 폴더/settings.json 생성

1
2
3
4
5
6
{
    "cSpell.words": [
        "reduxjs"
    ]
}
 
 

 

 

 

참고 자료

 

vscode 확장 Code Spell Checker

Code Spell Checker 확장에 대해 간단하게 알아보겠습니다. Visual Studio Marketplace에서 확인할 수 있습니다. 이 글은 v2.1.6 버전을 기준으로 작성되었습니다. 세 줄 요약 코드에서 자동으로 영어 스펠링

lawner.tistory.com

 

이 글은 [[한글자막] React 완벽 가이드 with Redux, Next.js, TypeScript]를 수강하며 정리한 글입니다.

 

 

⚛️ 기본 환경: IDE: VS code, Language: React

 

 

Redux toolKit 사용하기

1. Redux toolKit 설치

1
2
npm install @reduxjs/toolkit
 
 

 

2. createSlice import 및 선언

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
import {createSlice} from '@reduxjs/toolkit';
 
const initialState = {counter: 0, showCounter: true};
 
const counterSlice = createSlice({
    name'counter'// slice 이름
    initialState, // initialState: initialState와 동일
    reducers: {
        increment(state) {
            state.counter++;
        }, // 현재 상태를 변경한 것이 아니라 redux toolkit이 자동으로 원래 상태를 복제 후 새로운 상태 객체를 생성하여 반환
        decrement(state) {
            state.counter--;
        },
        increase(state, action) {
            state.counter = state.counter + action.payload;
        }, // action-payload: 추가 데이터
        toggleCounter(state) {
            state.showCounter = !state.showCounter;
        },
    }
});
 
 
 

⭐ redux 사용 시, 기존 state를 직접 변경하지 않도록 유의

⭐ state.counter++: 기존 state를 직접 업데이트한 것이 아니라 redux toolkit에 의해 만들어진 새로운 상태 객체를 업데이트 한 것

 

3. createSlice를 store에 등록

1
2
3
4
const store = configureStore({
    reducer: configureStore.reducer
});
 
 
 

cf. configureStore를 통한 reducer 병합

1
2
3
4
const store = configureStore({reducer: {
    counter: counterSlice.reducer
}}); configureStore-reducer: 모든 reducer를 하나의 큰 reducer로 병합
 
 
 

 

4. reducer 메서드에 접근하기 위한 slice의 actions 선언

: createSlice 함수의 reducer 영역에 있는 reducer method와 이름이 같은 메서드 호출 시 해당 메서드의 action 객체 생성

1
2
3
export const counterActions = counterSlice.actions;
// counterSlice.actions: return {type: 'some auto-generated unique identifier'}
 
 
 

 

5. action이 필요한 Component에서 import 후 실행

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
import { counterActions } from "../store/index";
 
const Counter = () => {
  const counter = useSelector((state) => state.counter);
  const show = useSelector((state) => state.showCounter);
  const dispatch = useDispatch();
 
  const incrementHandler = () => {
    dispatch(counterActions.increment());
  };
  const increaseHandler = () => {
    dispatch(counterActions.increase(5)); 
  }; // redux/toolkit: {type: SOME_UNIQUE_IDENTIFIER, payload: 5}
  const decrementHandler = () => {
    dispatch(counterActions.decrement());
  };
 
  const toggleCounterHandler = () => {
    dispatch(counterActions.toggleCounter());
 
    return (
      <main className={classes.counter}>
        <h1>Redux Counter</h1>
        {show && (
          <div className={classes.value}>-- COUNTER VALUE: {counter} --</div>
        )}
        <div>
          <button onClick={incrementHandler}>Increment</button>
          <button onClick={increaseHandler}>Increment by 5</button>
          <button onClick={decrementHandler}>Decrement</button>
        </div>
        <button onClick={toggleCounterHandler}>Toggle Counter</button>
      </main>
    );
  };
};
 
export default Counter;
 
 
 
 

redux/toolkit 내부에서 action 객체를 자동으로 생성

→ payload(추가 데이터)값의 key 이름을 payload로 자동으로 설정하였으므로 createSlice-reducer 선언 시 유의

 

이 글은 [[한글자막] React 완벽 가이드 with Redux, Next.js, TypeScript]를 수강하며 정리한 글입니다.

 

 

⚛️ 기본 환경: IDE: VS code, Language: React

 

 

useSelector(state => state.module)

: 저장소에 등록된 데이터(상태, State)를 가져와서 쓸 수 있는 Hook

 : Redux 스토어의 상태 객체를 매개변수로 받고, 그 상태에서 필요한 값을 선택적으로 반환
즉, Redux 상태 객체에서 counter 속성을 선택하여 반환

* useSelector 사용 시, react-redux는 해당 컴포넌트를 저장소에 자동으로 구독 설정

즉, 저장소 데이터가 변경될 경우에 자동으로 최신 카운터를 전달 받음

 

 

useDispatch()

: Redux 저장소에 action에 대한 type을 전달하여 상태 업데이트

 

 

사용 예시

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
import {useSelector, connect, useDispatch} from 'react-redux';
// useSelector: 저장소가 관리하는 데이터 access
// connect: class Component 사용할 경우 추가
// Class Component를 감싸는 Wrapper로 사용하여 Wrapper로 감싸진 Class Component를 저장소에 연결
 
import classes from './Counter.module.css';
 
const Counter = () => {
 
  const counter = useSelector(state => state.counter);
 
  const dispatch = useDispatch();
 
  const incrementHandler = () => {
    dispatch({type: 'increment'});
  };
  const decrementHandler = () => {
    dispatch({type: 'decrement'});
  };
 
  const toggleCounterHandler = () => {};
 
  return (
    <main className={classes.counter}>
      <h1>Redux Counter</h1>
      <div className={classes.value}>-- COUNTER VALUE: {counter} --</div>
      <div>
        <button onClick={incrementHandler}>Increment</button>
        <button onClick={decrementHandler}>Decrement</button>
      </div>
      <button onClick={toggleCounterHandler}>Toggle Counter</button>
    </main>
  );
};
 
export default Counter;
 
 
 

 

⚛️ 기본 환경: IDE: VS code, Language: React

 

 

발생 Error

React에서 다음 Source Code를 실행할 경우,

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
import redux from 'redux';
 
const counterReducer = (state = {counter: 0}, action) => {
    if(action.type === 'increment'){
        return {
            counter: state.counter + 1
        };
    }
    if(action.type === 'decrement'){
        return {
            counter: state.counter - 1
        };
    }
    return state;
};
 
const store = redux.createStore(counterReducer);
 
export default store;
 
 
 

🚨 다음과 같은 오류 발생

export 'default' (imported as 'redux') was not found in 'redux'

(possible exports: __DO_NOT_USE__ActionTypes, applyMiddleware, bindActionCreators, combineReducers, compose, createStore, legacy_createStore)

 

 

발생 원인

Redux 패키지는 기본적으로 객체 형태로 내보내기를 하고 있으며, default로 내보내는 항목이 없음
import redux from 'redux'와 같이 Redux 패키지를 가져오려고 할 경우 오류 발생

 

 

해결 방법

Redux 패키지에서 명시적으로 내보낸 함수나 객체를 선택적으로 가져올 수 있으므로 중괄호 {}를 사용하여 가져오고자 하는 항목을 지정

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
import {createStore} from 'redux';
 
const counterReducer = (state = {counter: 0}, action) => {
    if(action.type === 'increment'){
        return {
            counter: state.counter + 1
        };
    }
    if(action.type === 'decrement'){
        return {
            counter: state.counter - 1
        };
    }
    return state;
};
 
const store = createStore(counterReducer);
 
export default store;
 
 
 

 

이 글은 [[한글자막] React 완벽 가이드 with Redux, Next.js, TypeScript]를 수강하며 정리한 글입니다.

 

 

🟨 기본 환경: IDE: VS code, Language: JavaScript

 

 

Redux 작동 방식

Redux: Application 내부의 하나의 중앙 데이터(=상태, state) 저장소

Component: Redux를 구독하여 데어터가 변경될 때마다 필요한 데이터를 전달 받음

Reducer Function: 저장소의 데이터 변경(≠useReducer)

 - Input: Old State, Dispatched Action

 - Output: New State Object

Action: 버튼 클릭 등 이벤트의 발생

 - Component에서 일어나며(=Trigger) Reducer가 수행할 작업을 설명하는 객체

 - Redux는 Action을 Reducer로 전달하고 Reducer가 작업을 수행

Mutate: action을 수행한 Reducer가 새로운 상태를 Redux로 전달

 

 

Redux 사용 방법

1. redux.js 파일 생성

 

2. redux.js파일이 있는 곳에서 npm 설치

[Terminal]

1
2
3
npm init -y
npm install redux
 
 

 

3. Redux import

1
2
const redux = require('redux');
 
 
 

 

4. 저장소 및 Reducer 함수 생성

1
2
3
4
5
6
7
8
9
10
const redux = require('redux');
 
const counterReducer = (state = {counter: 0}, action) => {
    return {
        counter: state.counter + 1
    };
};
 
const store = redux.createStore(counterReducer);
 
 
 

* Reducer의 실행은 Redux가 함으로 함수명만 작성

 

5. Redux를 구독할 함수 및 Action 생성

1
2
3
4
5
6
7
const counterSubscriber = () => {
    const latestState = store.getState();
    console.log(latestState);
};
 
store.subscribe(counterSubscriber); // 데이터 변경 시 실행
 
 
 

* Subscribe Func의 실행은 Redux가 함으로 함수명만 작성

 

6. 파일 저장 및 실행

[Terminal]

1
node redux.js
 

 

7. Action 생성 및 발송

1
2
store.dispatch({type: 'increment'}); // Action(식별자 역할을 하는 타입 prop을 가진 객체) 발송
 
 
 

Action(식별자 역할을 하는 타입 prop을 가진 객체) 발송 → Reducer 호출 → 새로운 state 반환

 

8. counterReducer에서 type에 따른 로직 변경

1
2
3
4
5
6
7
8
9
10
const counterReducer = (state = {counter: 0}, action) => {
    if(action.type === 'increment'){
        return {
            counter: state.counter + 1,
        };
    }
 
    return state;
};
 
 
 

 

9. 파일 저장 및 실행

[Terminal]

1
2
3
4
node redux.js
 
# {counter: 1}