전역상태관리란 말하는바 그대로 전역에서 상태를 관리한다는 의미입니다.
리액트에서는 상위에서 하위로 상태값을 전달하여 상태를 관리하게 되어있습니다.
그러나 위와 같이 컴포넌트가 분리되어 점점 더 많아지는 컴포넌트에서 상태를 관리하게 위해서는 결국 props를 통해 사용하는 하위까지 값을 전달해야 합니다.
실제로 하위 컴포넌트에서 사용을 위해 불필요한 props를 전달받아야 하는 상황이 발생하고 props drilling
이라는 문제가 발생합니다.
Prop Drilling ?
Prop Drilling 은 props를 오로지 하위 컴포넌트로 전달하는 용도로만 쓰이는 컴포넌트들을 거치면서 React Component 트리의 한 부분에서 다른 부분으로 데이터를 전달하는 과정입니다.
React에서 Prop Drilling과 해결 방법
Prop Drilling
과 같은 문제로 인해 상태관리를 보다 편하고 불필요한 props 전달을 막을 필요가 생겼고 전역상태관리가 필요해졌습니다.
전역에서 상태관리를 하는 방법에는 리액트 Hook에서 제공하는 Context API 라는것을 제공합니다.
자세한 사항은 리액트 공식 사이트(리액트 Context)에서 확인 가능합니다.
리덕스는 현재 가장 많은 리액트 사용자가 사용하는 전역상태관리 입니다.
위에는 리덕스 공식 홈페이지에서 제공하는 메인 화면 입니다.
Redux는 자바스크립트 앱을 위한 예측 가능한 상태 컨테이너입니다.
Redux는 여러분이 일관적으로 동작하고, 서로 다른 환경(서버, 클라이언트, 네이티브)에서 작동하고, 테스트하기 쉬운 앱을 작성하도록 도와줍니다. 여기에 더해서 시간여행형 디버거와 결합된 실시간 >코드 수정과 같은 훌륭한 개발자 경험을 제공합니다.
Context API
는 react에서 정식적으로 지원하고 있는 전역상태관리 API 입니다.
일반적인 React 애플리케이션에서 데이터는 위에서 아래로 (즉, 부모로부터 자식에게) props를 통해 전달되지만, 애플리케이션 안의 여러 컴포넌트들에 전해줘야 하는 props의 경우 (예를 들면 선호 로케일, UI 테마) 이 과정이 번거로울 수 있습니다. context를 이용하면, 트리 단계마다 명시적으로 props를 넘겨주지 않아도 많은 컴포넌트가 이러한 값을 공유하도록 할 수 있습니다.
리액트 Context 에서 확인 할 수 있습니다.
우선 간단하게 todo 항목을 입력하는 부분과 렌더링 하는 부분을 추가하겠습니다.
context에 todo 리스트를 추가하는 todos와 todos의 상태를 바꿔줄 함수인 setTodos를 추가하겠습니다.
//TodoContext.js
import { createContext, useState, useContext } from "react";
const TodoContext = createContext(); // 1
export const TodoProvider = ({ children }) => {
const [todos, setTodos] = useState([]);
return (
<TodoContext.Provider value={{ todos, setTodos }}> // 2
{children}
</TodoContext.Provider>
);
};
export const TodoConsumer = TodoContext.Consumer; // 3
export const useTodoContext = () => useContext(TodoContext); // 4
Provider는 context를 구독(Consumer)하는 컴포넌트들에게 context의 변화를 알린다.
Todo를 감지할 컴포넌트를 provider로 감싸야 한다. 모든 페이지에서 로그인 여부를 알아야 하므로 최상단에 넣었다.
// App.js
import { TodoProvider } from "./TodoContext";
import Todo from "./Todo";
function App() {
return (
<TodoProvider>
<Todo />
</TodoProvider>
);
}
export default App;
TodoConsumer 내부에는 함수로 작성한다. 인자에 provider value에 할당했던 값이 전달 된다.
useContext를 통해 보다 쉽게 값을 사용할 수 있습니다.
import { useState } from "react";
import { TodoConsumer, useTodoContext } from "./TodoContext";
export default function Todo() {
const [input, setInput] = useState("");
const { todos, setTodos } = useTodoContext(); // 1
const handleInput = (e) =>setInput(e.target.value);
const handleSubmit = (e) => {
e.preventDefault();
setInput("");
setTodos((prev) => [...prev, input]); // 2
};
return (
<div>
<form onSubmit={handleSubmit}>
<input type="text" onChange={handleInput} />
</form>
<section>
<article>
useContext를 사용한 예제
{todos.map((todo) => (
<div>{todo}</div>
))}
</article> // 2
<TodoConsumer>
{({ todos }) => (
<article>
Consumer를 사용한 예제
{todos.map((todo) => (
<div>{todo}</div>
))}
</article>
)}
</TodoConsumer> // 3
</section>
</div>
);
}
context API를 간단하게 사용해봤습니다.
위 예제는 간단하게 구현한 것으로 useState를 통해 상태를 관리했지만 보다 복잡한 상태의 경우 useReduser을 통해 관리할 수 있습니다.
이전에도 한번 얘기했듯이 전역상태를 관리하는 여러방법들중 하나입니다.
리덕스 공식 문서에서는 다음과 같이 리덕스를 정의하고 있습니다.
리덕스에 들어가기 앞서 Flux패턴이라는것을 먼저 짚고 넘어가겠습니다.
우선 Flux패턴에 들어가기 전 MVC패턴에 대해서 알아보겠습니다.
관심사의 분리(separation of concern, SoC)에서부터 나온 패턴입니다.
관심사 분리로 코드의 단순화 및 유지보수의 더 높은 수준의 자유가 생긴다.
관심사가 잘 분리될 때 독립적인 개발과 업그레이드 외에도 모듈 재사용을 위한 더 높은 정도의 자유가 있다.
모듈이 인터페이스 뒤에서 이러한 관심사의 세세한 부분을 숨기기 때문에 자유도가 높아짐으로써 다른 부분의 세세한 사항을 모르더라도, 또 해당 부분들에 상응하는 변경을 취하지 않더라도 하나의 관>심사의 코드 부분을 개선하거나 수정할 수 있게 된다.
Flux 패턴의 경우 기존 MVC패턴의 문제점에서 나온 패턴이라고 합니다.
이 프로젝트는 파생되는 데이터를 올바르게 다루기 위해 시작되었다. 예를 들면 현재 뷰에서 읽지 않은 메시지가 강조되어 있으면서도 읽지 않은 메시지 수를 상단 바에 표시하고 싶었다. 이런 부분은 MVC에서 다루기 어려운데 메시지를 읽기 위한 단일 스레드에서 메시지 스레드 모델을 갱신해야하고 동시에 읽지 않은 메시지 수 모델을 갱신 해야하기 때문이다.
그렇다면 왜 리덕스를 사용하기 전에 Flux 패턴에 대해 알아봤을까요?
Redux는 Flux 패턴을 근본으로한 라이브러리이다.
React 뿐 아니라 다른 UI 라이브러리에서도 사용할 수 있다.
Store: Application의 전체 state는 store라고 불리는 곳에서 관리된다.
Action: action은 state 변화를 일으킬 수 있는 행동정보, 현상등이라고 생각하면 된다.
Dispatcher: action이 일어나면 Dispatcher를 통해서 store의 state가 업뎃된다.
View: state가 변경되면 view에서 감지하고, 화면에 반영(render) 된다.
위의 그림과 같이 view단에서 action이 일어날 수도 있다(당연). view에서 action이 일어나면 -> 다시 dispatcher에 의해 store에 저장되고 -> state가 변경되면 -> 필요한 view에서 감지를 알아차린다.
순수함수(Pure function)란?
항상 같은 input은 항상 같은 output을 반환하는 함수.
한주를 보내며 느낀건 정말 공부가 많이 필요하다는거다..
이번 개인 과제는 정말 힘들었다. 머 지금 까지 과제들 모두가 힘들었지만 이번엔 정말 힘들었다. 너무 모르다보니 그저 따라가기에만 바뻐 중요한 개념들을 무시하고 넘어갔던거 같다.
이렇게 주말을 정리하면서 많이 느낀다.
그리고 그것을 꼭 해야된다는걸 많이 느낀다.
물론 TIL은 계속 쓰고있지만 앞으론 이게 왜 생겼고 왜 사용하는지 어떻게 사용하는지에 대해 따로 공부하는 시간을 따로 가질까한다.
한주가 너무 힘들어서 난 안되나 생각많이 했다.
이겨내자 분명히 익숙해지고 익숙해지면 잘할수있을꺼라고 믿는다.😊