티스토리 뷰

리덕스

https://velog.io/@hwang-eunji/%EB%A6%AC%EB%8D%95%EC%8A%A4-%EC%A0%95%EB%A6%AC-redux-1

 

리덕스+리액트 Redux with React #1 설치와 리덕스 개념

리덕스 Redux 공식문서 스토어라는 가상공간에 데이터를 모아두어, 필요한 컴포넌트에서 데이터를 가져다 사용,변경 할수 있다.중간 컴포에게 데이터전달-전달-전달 하지 않고, 중앙관리되는 데

velog.io

https://velog.io/@lchyung1998/React-Redux-Saga-%EC%83%81%ED%83%9C%EA%B4%80%EB%A6%AC%EB%A5%BC-%EB%81%9D%EC%9E%A5%EB%82%B4%EB%B2%84%EB%A0%B8%EB%8B%A4#reducer

 

[React] Redux + Saga, 상태관리를 끝장내버렸다.

Redux + Saga, 액션 생성 함수는 객체만 반환하며!! 비동기 처리하기

velog.io

[ERROR]

ERESOLVE unable to resolve dependency tree

▼ 해결 방법

https://www.korecmblog.com/ERESOLVE-unable-to-resolve-dependency-tree/

 

ERESOLVE unable to resolve dependency tree 해결하기

상황 블로그를 만들기 위해 Gatsby Starter 메뉴얼에 따라서 아래 명령어를 실행했다. 공식 문서에서 제공하는 설치 방법임에도 불구하고 아래와 같은 오류가 발생했다. 자세히 오류를 살펴보면 아

www.korecmblog.com

리덕스 데브 툴즈

https://bigstar-vlog.tistory.com/47

 

[React] Redux DevTools 사용하기

안녕하세요, 황대성입니다😁 오늘은 Redux를 조금 더 효율적으로 관리할 수 있는 Chrome 확장 프로그램을 사용해봅시다. 따라하기 굉장히 쉬우니 여러분들도 한 번 사용해보셨으면 좋겠습니다. 제

bigstar-vlog.tistory.com

https://seongjins.tistory.com/219

 

react-devtools 설치

1. react-devtools를 설치 $ npm i react-devtools $ npm install -g react-devtools 2. react-devtools를 실행 $ react-devtools 명령어를 실행하면 아래와 프로그램이 실행되고 모바일 expo에서 QR코드를 찍고 reload를 했을때 아

seongjins.tistory.com

리덕스 툴킷

https://velog.io/@ih9137/React-Redux-toolkit-%EC%84%A4%EC%B9%98-%EB%B0%8F-%EC%82%AC%EC%9A%A9%EB%B0%A9%EB%B2%95

 

[React] Redux-toolkit 설치 및 사용방법

Redux를 조금 더 쉽게 사용하기 위해 만든 Redux-toolkit에 대해 알아보려고 한다. 일단은 npm으로 Redux-toolkit을 다운로드 한다. 그리고 메인이 되는 파일(app.jsx 또는 app.tsx)로 가서 아래와 같이 코드를

velog.io

피그마 플러그인

https://ossam5.tistory.com/304

 

[Figma] 19강 오쌤 Pick! 피그마 플러그인 Top 10 - 오쌤의 니가스터디

** 영상으로 보고 싶은 분은 아래 주소를 클릭하세요. https://youtu.be/z3_hjBFItXk 0. 피그마 플러그인 검색 및 설치 - 블로그에 글을 쓰려고 피그마를 켰는데 또 새로운 기능이 나왔습니다. - 그래서 예

ossam5.tistory.com

https://yozm.wishket.com/magazine/detail/1102/

 

피그마 작업 시 유용한 플러그인 Top3 | 요즘IT

피그마의 장점은 많지만 저는 크게 두 가지로 생각하고 있는데요. 하나는 프로그램을 설치하지 않아도 웹 브라우저만 있다면 언제, 어디서든 함께 작업을 할 수 있다는 점입니다. 그리고 플러그

yozm.wishket.com

https://brunch.co.kr/@hailey-hyunjee/59

 

UX 디자이너의 피그마에 설치된 플러그인의 모든 것

나만 알고 싶은 유용한 피그마 플러그인 리스트 | 2020년은 그야말로 피그마의 해였다. 디자인 업계에서 코로나19의 최대 수혜자 중 하나는 피그마 툴이 아닐까? 2019년 초부터 피그마를 사용하고

brunch.co.kr

동영상 git로 변환

https://ezgif.com/

 

Animated GIF editor and GIF maker

Easy to use online animated GIF maker and image editor. Upload and edit GIF images for free. Create, crop, resize, reverse, optimize and split animated GIFs, cut and resize videos, WebP and APNG animations.

ezgif.com

리액트 심화 주차 강의

A. Redux Toolkit

*npm으로 json 서버 실행하기

npx json-server --watch db.json

※ 일반 리덕스를 사용한 경우 우리가 직접 Action Value와 Action Creator를 만들었다.

 

* modules - counterSlice.js 전체 코드

// src/redux/modules/counterSlice.js

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

const initialState = {
  number: 0,
};

const counterSlice = createSlice({
  name: "counter",
  initialState,
  reducers: {
    addNumber: (state, action) => {
      state.number = state.number + action.payload;
    },

    minusNumber: (state, action) => {
      state.number = state.number - action.payload;
    },
  },
});

// 액션크리에이터는 컴포넌트에서 사용하기 위해 export 하고
export const { addNumber, minusNumber } = counterSlice.actions;
// reducer 는 configStore에 등록하기 위해 export default 합니다.
export default counterSlice.reducer;

위와 같이 리덕스 툴킷을 사용한 경우 Action value, Action Creator, reducer 3개가 합쳐짐

1. createSlice라는 toolkit의 api를 통해서 만들 수 있음

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

slice

When you call createApi, it automatically generates and returns an API service "slice" object structure containing Redux logic you can use to interact with the endpoints you defined. This slice object includes a reducer to manage cached data, a middleware to manage cache lifetimes and subscriptions, and selectors and thunks for each endpoint. If you imported createApi from the React-specific entry point, it also includes auto-generated React hooks for use in your components.

https://redux-toolkit.js.org/rtk-query/api/created-api/overview

 

Overview | Redux Toolkit

 

redux-toolkit.js.org

2. name 이름 initialState 초기 상태 값 그리고 module의 reducer 로직이 인자로 들어가면 됨

//createSlice API 뼈대

const counterSlice = createSlice({
	name: '', // 이 모듈의 이름
	initialState : {}, // 이 모듈의 초기상태 값
	reducers : {}, // 이 모듈의 Reducer 로직
})

createSlice라는 API는 인자로 설정 정보를 객체로 받는다.

-> 설정 정보를 객체로 받는다는 게 무슨 말일까?

redux toolkit에는 createSlice라는 action type, action 생성자 및 action 객체를 생성하는 작업을 하는 함수가 있습니다. slice의 이름을 정의하고, 그 안에 reducer 기능이 있는 객체를 작성하면 자동으로 생성됩니다. name 옵션은 각 action type의 첫번째 부분으로 사용되며 각 reducer의 기능을 담당하는 함수의 이름은 두번째 부분으로 사용됩니다.
예를들어 name을 "counter"로 설정하고, reducer의 기능 함수 이름을 "increment"설정하면 둘이 합쳐져서 { type: "counter/increment" } 이라는 action이 생성 됩니다.
name 필드 외에도 createSlice에 initialState를 전달하여 초기 state가 호출 될 수 있도록 해야합니다. 

counterSlice라는 slice의 이름을 정의하고 { } 객체를 작성

3. Reducer의 logic인 동시에 Action Creater가 된다!!! Action Value도 함수의 이름을 따서 자동 생성됨 

so 우리는 Reducer만 만들면 됨

// counterSlice.js의 Slice 구조

const counterSlice = createSlice({
  name: "counter",
  initialState,
  reducers: {
    // 리듀서 안에서 만든 함수 자체가 리듀서의 로직이자, 액션크리에이터가 된다.
    addNumber: (state, action) => {
      state.number = state.number + action.payload;
    },

    minusNumber: (state, action) => {
      state.number = state.number - action.payload;
    },
  },
});

addNumber와 minusNumber 함수의 이름이 Action value가 되고 이 로직을 이용해서 reducer에 로직과 Action Creator가 생성됨

4. Action Creator 는 컴포넌트에서 사용하기 위해 export 합니다.

일반 redux에서는 export를 통해 각각의 Action Creator를 내보내 줬었는데 아래와 같이 작성하면 똑같이 내보낼 있음.

export const { addNumber, minusNumber } = counterSlice.actions;

// reducer 는 configStore에 등록하기 위해 export default 합니다.

export default counterSlice.reducer;

So reducer 로직이 추가될 때마다 객체 안에 함수만 추가해서 내보내주면


*configStore-redux

// 일반 리덕스 combineReducers 예시 코드

import { createStore } from "redux";
import { combineReducers } from "redux";
import counter from "../modules/counter";

const rootReducer = combineReducers({
  counter,
});
const store = createStore(rootReducer);
export default store;

combineReducers와 createStore 이렇게 두 가지 method를 이용하고 있음.

ㄱ. combineReducer를 통해서 module이 여러 개일 때  roofReducer로 합쳐주고

ㄴ. 그 rootReducer를 createStore 안에 인자로 넣어줘서

-> store를 생산하는 두 가지 과정을 거치고 있었음

 

<-> configStore - redux toolkit

1. modules 합치고 store 생성하기

// src/redux/modules/config/configStore.js

import { configureStore } from "@reduxjs/toolkit";
/**
 * import 해온 것은 slice.reducer 입니다.
 */
import counter from "../modules/counterSlice";
import todos from "../modules/todosSlice";

/**
 * 모듈(Slice)이 여러개인 경우
 * 추가할때마다 reducer 안에 각 모듈의 slice.reducer를 추가해줘야 합니다.
 *
 * 아래 예시는 하나의 프로젝트 안에서 counter 기능과 todos 기능이 모두 있고,
 * 이것을 각각 모듈로 구현한 다음에 아래 코드로 2개의 모듈을 스토어에 연결해준 것 입니다.
 */
const store = configureStore({
  reducer: { counter: counter, todos: todos },
});

export default store;

configStore라는 method 하나로 module을 합치는 것과 store를 생성하는 것을 한 번에 하고 있음.

모듈이 추가되면 reducer : {counter: counter} 객체 안에 module을 추가로 넣어주면 됨

*todos.Slice

// src/redux/modules/todosSlice.js

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

const initialState = {
  todos: [],
};

const todosSlice = createSlice({
  name: "todos",
  initialState,
  reducers: {},
});

export const {} = todosSlice.actions;
export default todosSlice.reducer;

2. 생성한 store를 최상위 index.js 에 추가하는 과정

* Index.js

// index.js

import React from "react";
import ReactDOM from "react-dom/client";
import App from "./App";
import { Provider } from "react-redux";
import store from "./redux/config/configStore";

const root = ReactDOM.createRoot(document.getElementById("root"));
root.render(
  <Provider store={store}>
    <App />
  </Provider>
);

*App.js - 위의 <App />

// src/App.js

import React from "react";
import { useSelector } from "react-redux";

const App = () => {
  // Store에 있는 todos 모듈 state 조회하기
  const todos = useSelector((state) => state.todos);

  // Store에 있는 counter 모듈 state 조회하기
  const counter = useSelector((state) => state.counter);

  return <div>App</div>;
};

export default App;

1 ~ 2 의 내용 ] store를 export default 가져와서 root의 provider에 store를 넣어주는 과정은 Redux 와 redux toolkit 동일,

그리고 그 값을 가지고 와서 사용하는 방법도 동일함

 

즉, useSelector를 이용해서 state안의 값을 가지고 와서 확인할 수 있다는 부분 동일함

toolkit에서도 useSelector state에서 원하는 값으로 접근해서 가져오면 됨

✔️ 결론 : Toolkit에 slice api를 이용해서 reducer, ActionValue, Action Creater를 한 번에 구현할 수 있다.

* 내장된 주요 패키지 thunk, devTools, immer 등이 있음

 

- 폴더 구조 예시

더보기
  • /src
    • index.js: 앱의 시작점
    • App.js: 최상위 React 컴포넌트
    • /app
      • store.js: Redux 스토어 인스턴스 생성
    • /features
      • /counter
        • Counter.js: 카운터 기능에 대한 UI를 보여주는 React 컴포넌트
        • counterSlice.js: 카운터 기능에 대한 Redux 로직

https://jcon.tistory.com/181

 

redux 강의 기본 핵심 튜토리얼 3탄 - redux app 구조

이전 포스트에서 redux의 용어와 개념에 대해서 설명했습니다. 이번 포스트에서는 실제 코드 예제를 살펴보고 어떻게 동작이 되는지 살펴 보겠습니다. 카운터 앱 예제 살펴볼 샘플 프로젝트는 버

jcon.tistory.com

 

- immer

더보기

 

 - immer

Immer 를 사용하면 우리가 상태를 업데이트 할 때, 불변성을 신경쓰지 않아도 대신 불변성을 관리해줌!

import produce from 'immer';
...

const state = {
  number: 1,
  dontChangeMe: 2
};

const nextState = produce(state, draft => {
  draft.number += 1;
});

console.log(nextState);
// { number: 2, dontChangeMe: 2 }

*produce 함수를 사용 할 때에는 첫번째 파라미터에는 수정하고 싶은 상태, 두번째 파라미터에는 어떻게 업데이트하고 싶을지 정의하는 함수를 넣어줌.

draft.number += 1;

이렇게 불변성을 신경쓰지 않고 업데이트를 해도 알아서 불변성을 관리함

 

Immer 함수형 업데이트

함수형 업데이트를 하는 경우에, Immer 를 사용하면 상황에 따라 더 편하게 코드를 작성 할 수 있음

const [todo, setTodo] = useState({
  text: 'Hello',
  done: false
});

const onClick = useCallback(() => {
  setTodo(
    produce(draft => {
      draft.done = !draft.done;
    })
  );
}, []);

...

// ~ 결과{ text: 'Hello', done: true }

produce 함수에 첫번째 파라미터를 생략하고 바로 업데이트 함수를 넣어주게 된다면, 반환 값은 '새로운 상태가 아닌 상태'를 업데이트 해주는 함수가 됨(done만 업데이트되어 '새로운 상태가 아닌 상태'가 됨)

즉, produce 가 반환하는것이 업데이트 함수가 되기 때문에 useState 의 업데이트 함수를 사용 할 떄 위과 같이 구현 할 수 있음

https://react.vlpt.us/basic/23-immer.html

 

23. Immer 를 사용한 더 쉬운 불변성 관리 · GitBook

23. Immer 를 사용한 더 쉬운 불변성 관리 리액트에서 배열이나 객체를 업데이트 해야 할 때에는 직접 수정 하면 안되고 불변성을 지켜주면서 업데이트를 해주어야 합니다. 예를 들자면 다음과 같

react.vlpt.us

더보기

# Immer simplifies handling immutable data structures

Without Immer

Without Immer, we'll have to carefully shallow copy every level of the state structure that is affected by our change:

const nextState = baseState.slice() // shallow clone the array
nextState[1] = {
    // replace element 1...
    ...nextState[1], // with a shallow clone of element 1
    done: true // ...combined with the desired update
}
// since nextState was freshly cloned, using push is safe here,
// but doing the same thing at any arbitrary time in the future would
// violate the immutability principles and introduce a bug!
nextState.push({title: "Tweet about it"})

With Immer

import produce from "immer"

const nextState = produce(baseState, draft => {
    draft[1].done = true
    draft.push({title: "Tweet about it"})
})

https://immerjs.github.io/immer/#immer-simplifies-handling-immutable-data-structures

 

Introduction to Immer | Immer

Immer

immerjs.github.io

 

 

- Flux

더보기

Action Creator - like a telegraph operator

액션 생성자는 타입(type)과 페이로드(payload)를 포함한 액션을 생성한다. 타입은 시스템에 정의 된 액션들(일반적으로 상수들) 중의 하나이다. 액션 생성자가 액션 메시지를 생성한 뒤에는 디스패쳐(dispatcher)로 넘겨준다.

 

Dispatcher - like a telephone operator

 디스패쳐는 액션을 보낼 필요가 있는 모든 스토어(store)를 가지고 있고,

액션 생성자로부터 액션이 넘어오면 여러 스토어에 액션을 보낸다.

- 이 처리는 동기적으로(synchronously) 실행된다.

- 스토어들 사이에 의존성(dependency)이 있어서 하나를 다른 것보다 먼저 업데이트를 해야한다면, waitFor()를 사용해서 디스패쳐가 적절히 처리하도록 할 수 있다.

 

Store - like a government official

애플리케이션 내의 모든 상태와 그와 관련된 로직을 가짐. 모든 상태 변경을 결정한다.

- 스토어에 상태 변경을 요청하기 위해서는 Action Creator / Dispatcher pipeline을 통해 Action을 보내야 함

- 디스패쳐에 등록된 스토어는 모든 Action을 받는데, switch statement로 처리/무시할 Action을 정하고, 처리할 Action에 따라 '무엇을 할 지' 결정한 후 state 상태를 변경한다. 이렇게 상태 변경을 완료하면 스토어는 change event 변경 이벤트를 내보내고 그 이벤트는 controller view에 state변경했음을 알려준다.

 

View, Controller View - like a presenter

ㅇ View : 애플리케이션 내부에 대해서는 아는 것이 없지만, 받은 데이터를 처리해서 사람들이 이해할 수 있는 포맷(HTML)으로 어떻게 바꾸는지

Controller View : 스토어와 뷰 사이의 중간관리자. 상태가 변경되었을 때 스토어가 그 사실을 컨트롤러 뷰에게 알려주면, 컨트롤러 뷰는 자신의 아래에 있는 모든 뷰에게 새로운 상태를 넘겨준다.

 

어떻게 함께 동작하는가? - 아래 링크

https://bestalign.github.io/translation/cartoon-guide-to-flux/

 

Flux로의 카툰 안내서

원문: https://medium.com/code-cartoons/a-cartoon-guide-to-flux-6157355ab207 Flux…

bestalign.github.io

 

- Flux와 Redux

더보기

Reducer

리듀서(Reducer)는 Flux에는 없는, Redux에서만 찾을 수 있는 용어이다.
액션은 어떤 일이 일어났는지는 알려주지만 애플리케이션의 상태를 어떻게 바꾸어야 할지는 알려주지 않는데, Redux 프레임워크에서는 리듀서가 이 역할을 담당한다.
간단히 말해 Flux 애플리케이션에서 스토어 객체를 업데이트하는 콜백 함수와 하는 역할은 비슷하다.

다만, Flux 스토어의 콜백과는 달리 Array.prototype.reduce(리듀서콜백, ?초기값)에 전달된 리듀서콜백처럼 동작하기에 리듀서(reducer)라고 부른다.

 

Todo 애플리케이션에 다음과 같은 상태 객체가 있다고 생각해보자.

{
  visibilityFilter: 'SHOW_ALL',
  todos: [
    {
      text: '자료 준비하기',
      completed: true
    },
    {
      text: '블로그 글쓰기',
      completed: false
    }
  ]
}

이 데이터를 업데이트하는 함수 todoApp은 다음과 같이 작성할 수 있다.

function todoApp(state = initialState, action) {
  switch (action.type) {
    case SET_VISIBILITY_FILTER:
      return Object.assign({}, state, {
        visibilityFilter: action.filter
      });
    default:
      return state;
  }
}

위 코드의 todoApp은 인수만 전달받던 Flux의 스토어 콜백과는 달리 첫 번째 인수로 기존 상태를 전달받고, 두 번째 인수로 액션 객체를 전달받는다.
리듀서를 작성할 때는 두 가지 사항을 유의해야 한다.

  1. 첫 번째 인수로 전달받은 state는 수정하면 안된다.
    상태를 수정할 때는 반드시 Object.assign 등을 사용하여 새로운 객체를 만들어서 반환해야 한다.
  2. default 케이스에서 기존 state를 반환해야 한다.
    전달받은 액션 객체를 이 리듀서에서 처리하지 못하는 때를 대비해 default 케이스에서는 반드시 인수로 전달받은 state를 그대로 반환해야 한다.

https://taegon.kim/archives/5288

 

Flux와 Redux

이 글에서는 Facebook에서 React와 함께 소개한 Flux 아키텍처에 대해 알아보고 Flux를 구현한 Redux 라이브러리를 살펴본 후 이를 적용한 간단한 React 애플리케이션을 작성해보겠다. 본문에 사용된 코

taegon.kim

 

+ to do list 에서

Action Creator 

// modules의 todos.js

Dispatcher 

// Form.jsx - Create 새로운 todo 만드는 dispatch(addTodo(newTodo));

// Todo.jsx - Update 만들어진 todo의 isDone 상태에 따라 달라지는 dispatch(toggleTodo(id));

// Todo.jsx - Delete 만들어진 todo를 지우는 dispatch(deleteTodo(id));

// Details.jsx - Read 상세페이지에서 todo 정보를 읽어오는 dispatch(getTodoByID(id)

👊🏻 오늘 한 일

  • [혼공자] 언어 스터디 Ch9-2 클래스 고급 
  • 심화 주차 팀 회의
  • 와이어프레임 완료
  • redux toolkit 강의

😲 오늘 느낀 점

뭔가 더 많은 일을 한 것 같은데 오늘 아침이 일주일 전처럼 기억이 잘 안 난다. 그때그때 적으면서 TIL을 쓰고 나중에 정리하려고 했는데 너무 피곤해서 메모한 내용만 옮겨놓고 잠들었다. 조금 자고 일어나도 피곤하지 않았으면 좋겠다. 이제 리액트 툴킷을 사용해서 팀 프로젝트가 시작된다. 매일매일이 숨 가쁘게 달리는 것 같다. 이것저것 다시 복습하고 하나씩 톺아볼 시간이 필요하다. 내가 좀 더 똑똑했으면 좋겠다.

👏🏻 오늘의 칭찬

팀 회의가 생각보다 재밌었다. 넣고 싶은 기능들이 많은데 시간을 아껴서 한 번 다 구현해보고 싶다.

🤔 오늘 아쉬운 점

해야 할 일, 하고 싶은 일, 계획한 일은 많은데 모두 지키지 못했다. 내 능력은 저기 아래인데 욕심은 많아서 스트레스를 받지만 그래도 최선을 다해야 한다...

⛵️ 내일 할 일

  • redux toolkit 강의
  • 심화 주차 강의자료 + 공식 문서, 블로그 등