>  기사  >  웹 프론트엔드  >  Redux 이해: 초보자를 위한 종합 가이드

Redux 이해: 초보자를 위한 종합 가이드

王林
王林원래의
2024-08-24 11:06:02788검색

Understanding Redux: A Beginner

소개: Redux는 무엇이며 왜 필요한가요?

웹 애플리케이션이 복잡해짐에 따라 상태 관리가 점점 더 어려워지고 있습니다. 예측할 수 없는 상태 변화와 추적하기 어려운 데이터 흐름의 웹에 얽혀 있는 자신을 발견했다면 혼자가 아닙니다. Redux가 생명의 은인으로 등장하는 곳입니다.

Redux는 JavaScript 애플리케이션용 상태 관리 라이브러리로, 특히 React와 함께 사용할 때 효율성이 뛰어난 것으로 유명합니다. 애플리케이션 상태를 관리하는 예측 가능하고 중앙 집중화된 방법을 제공함으로써 Redux는 시간에 따른 데이터 변경 방식과 애플리케이션의 다양한 부분이 서로 상호 작용하는 방식을 추적하는 프로세스를 단순화합니다.

그런데 Redux가 왜 필요한가요? 대규모 애플리케이션에서는 상태 변경이 여러 위치에서 발생할 수 있으므로 특정 데이터 조각이 어디서 어떻게 변경되었는지 정확히 파악하기가 어렵습니다. 이러한 애플리케이션을 디버깅하고 유지하는 것은 악몽이 될 수 있습니다. Redux는 전체 애플리케이션의 상태를 스토어라는 단일 중앙 집중식 장소에 저장하여 이러한 문제를 해결합니다. 이러한 중앙 집중식 접근 방식은 상태 관리를 단순화할 뿐만 아니라 애플리케이션의 예측 가능성과 테스트 가능성도 향상시킵니다.

이 가이드는 Redux의 핵심 개념 이해부터 React 애플리케이션에서의 설정 및 사용에 이르기까지 Redux를 통한 자세한 여정을 안내합니다. 이 기사를 마치면 Redux를 확실히 이해하고 이를 프로젝트에 적용할 수 있는 준비를 갖추게 될 것입니다.

Redux의 핵심 개념

Redux를 제대로 이해하려면 저장, 액션, 리듀서라는 세 가지 기본 개념을 숙지하는 것이 중요합니다. 각 개념에 대해 자세히 알아보겠습니다.

1. 매장: 진실의 단일 소스

Redux의 중심에는 애플리케이션의 전체 상태를 보관하는 중앙 저장소인 스토어가 있습니다. 스토어는 앱 데이터의 단일 정보 소스입니다. 애플리케이션의 규모나 복잡도에 관계없이 모든 상태가 한 곳에 저장되므로 관리 및 디버깅이 더 쉽습니다.

스토어를 애플리케이션이 작동하는 데 필요한 모든 정보를 포함하는 거대한 JavaScript 개체로 상상해 보세요. 사용자 데이터, UI 상태, 서버 응답 등 모든 것이 이 개체에 저장됩니다. 이러한 중앙 집중식 접근 방식은 개별 구성 요소 내에서 로컬로 상태를 관리하는 기존 방법과 대조되며, 이로 인해 상태 변경을 추적하는 데 불일치와 어려움이 발생할 수 있습니다.

Redux의 저장소는 불변입니다. 즉, 일단 상태가 설정되면 직접 변경할 수 없습니다. 대신 변경이 필요할 때마다 새 상태가 생성됩니다. 이러한 불변성은 각 상태 변경이 의도적이고 추적 가능하도록 보장하므로 애플리케이션의 예측 가능성을 유지하는 데 중요합니다.

2. 행동: 무슨 일이 일어났는지 설명하기

Redux의 작업은 애플리케이션의 이벤트나 변경 사항을 설명하는 일반 JavaScript 개체입니다. 그들은 앱에서 일어난 일에 대한 정보를 전달하는 메신저와 같습니다. 각 작업에는 작업의 특성을 정의하는 유형 속성과 선택적으로 작업과 관련된 추가 데이터가 포함된 페이로드 속성이 있습니다.

예를 들어 할 일 목록 애플리케이션에서 작업은 새 할 일 항목 추가, 기존 항목 완료 또는 항목 삭제를 나타낼 수 있습니다. 이러한 각 작업에는 ADD_TODO, TOGGLE_TODO 또는 DELETE_TODO와 같은 고유한 유형이 있으며 할 일의 ID 또는 텍스트와 같은 추가 데이터가 포함될 수 있습니다.

액션은 스토어로 전달되고 리듀서(다음에 설명)에 의해 처리됩니다. 애플리케이션에서 발생한 일을 명확하게 정의함으로써 작업은 데이터 변경의 명확하고 이해 가능한 흐름을 유지하는 데 도움이 됩니다.

3. 리듀서: 상태 변경 방법 정의

리듀서는 작업에 대한 응답으로 애플리케이션의 상태가 어떻게 변경되어야 하는지를 정의하는 Redux의 순수 함수입니다. 현재 상태와 작업을 인수로 사용하고 새 상태를 반환합니다. "순수 함수"라는 용어는 감속기의 출력이 입력(현재 상태 및 동작)에만 의존하고 외부 변수를 수정하거나 비동기 작업을 수행하는 등의 부작용을 생성하지 않는다는 것을 의미합니다.

Redux에서는 리듀서가 실제 상태 업데이트를 담당합니다. 액션이 전달되면 Redux는 현재 상태와 액션을 적절한 리듀서에 전달한 다음 새 상태를 계산하고 반환합니다. 이 프로세스를 통해 예측 및 추적 가능한 방식으로 상태가 변경됩니다.

예를 들어 할 일 목록 애플리케이션용 리듀서는 다음과 같습니다.

function todoReducer(state = [], action) {
  switch (action.type) {
    case 'ADD_TODO':
      return [...state, action.payload];
    case 'TOGGLE_TODO':
      return state.map(todo =>
        todo.id === action.payload.id
          ? { ...todo, completed: !todo.completed }
          : todo
      );
    default:
      return state;
  }
}

이 예에서 todoReducer는 ADD_TODO 및 TOGGLE_TODO라는 두 가지 유형의 작업을 처리합니다. 작업 유형에 따라 새 할 일 항목을 상태에 추가하거나 기존 항목의 완료 상태를 전환합니다. 리듀서는 항상 새로운 상태 객체를 반환하여 원래 상태가 변경되지 않도록 보장합니다.

Redux 설정 및 사용: 자세한 단계별 가이드

이제 Redux의 핵심 개념을 다루었으므로 실제 애플리케이션에서 이러한 개념이 어떻게 결합되는지 살펴보겠습니다. 이 섹션에서는 간단한 React 애플리케이션에서 Redux를 설정하고 사용하는 과정을 살펴보겠습니다.

1단계: Redux 및 관련 패키지 설치

Redux를 사용하는 첫 번째 단계는 필요한 패키지를 설치하는 것입니다. Redux 자체는 독립형 라이브러리이지만 React와 함께 사용하는 경우 Redux를 React 구성 요소와 통합하기 위한 바인딩을 제공하는 패키지인 React-redux도 설치하는 것이 좋습니다.

Redux 및 React-Redux를 설치하려면 터미널을 열고 프로젝트 디렉터리에서 다음 명령을 실행하세요.

npm install redux react-redux

이 명령은 React 구성요소를 Redux 스토어에 연결하는 데 사용할 redux와 React-redux를 모두 설치합니다.

2단계: 스토어 생성

Redux가 설치되면 다음 단계는 스토어를 생성하는 것입니다. 스토어는 애플리케이션의 상태를 보유하고 작업을 전달하고 상태 변경을 구독하는 방법을 제공합니다.

이 예에서는 간단한 할 일 목록 애플리케이션을 위한 스토어를 생성하겠습니다. 상태 변경을 처리할 감속기 함수를 만드는 것부터 시작하세요.

import { createStore } from 'redux';

// This is our reducer function
function todoReducer(state = [], action) {
  switch (action.type) {
    case 'ADD_TODO':
      return [...state, action.payload];
    case 'TOGGLE_TODO':
      return state.map(todo =>
        todo.id === action.payload.id
          ? { ...todo, completed: !todo.completed }
          : todo
      );
    default:
      return state;
  }
}

// Create the store
const store = createStore(todoReducer);

이 코드에서 todoReducer 함수는 두 가지 유형의 작업, 즉 새 할 일 항목을 추가하는 ADD_TODO와 항목의 완료 상태를 전환하는 TOGGLE_TODO를 처리합니다. Redux의 createStore 함수는 저장소를 생성하는 데 사용되며 todoReducer를 인수로 전달합니다.

3단계: 액션 및 액션 생성자 정의

Redux에서는 애플리케이션에서 발생한 일을 설명하는 작업이 필수적입니다. 그러나 액션을 전달하려고 할 때마다 액션 객체를 수동으로 생성하는 것은 번거로울 수 있습니다. 여기서 액션 생성자가 등장합니다. 액션 생성자는 액션 객체를 반환하는 함수입니다.

할 일 항목을 추가하기 위한 액션 생성자를 정의해 보겠습니다.

function addTodo(text) {
  return {
    type: 'ADD_TODO',
    payload: { id: Date.now(), text, completed: false }
  };
}

addTodo 함수는 텍스트 인수를 사용하여 ADD_TODO 유형과 할 ​​일 항목 데이터가 포함된 페이로드가 있는 작업 객체를 반환합니다. 이 액션 생성기는 액션 전달 프로세스를 단순화하여 코드를 더 읽기 쉽고 유지 관리하기 쉽게 만듭니다.

Todo 항목의 완료 상태를 전환하기 위해ggleTodo와 같은 다른 액션 생성자를 정의할 수도 있습니다.

function toggleTodo(id) {
  return {
    type: 'TOGGLE_TODO',
    payload: { id }
  };
}

4단계: 상태 업데이트를 위한 작업 디스패치

저장소와 액션이 준비되었으면 이제 액션을 전달하여 상태를 업데이트할 수 있습니다. 액션 디스패칭은 애플리케이션에서 어떤 일이 발생했음을 Redux에 알리고 적절한 리듀서를 트리거하여 상태를 업데이트하는 방법입니다.

할 일 항목을 추가하고 전환하는 작업을 전달하는 방법은 다음과 같습니다.

store.dispatch(addTodo('Learn Redux'));
store.dispatch(addTodo('Build an app'));
store.dispatch(toggleTodo(1621234567890));

addTodo 액션을 전달하면 Redux는 현재 상태와 액션으로 todoReducer를 호출하고 리듀서는 추가된 todo 항목이 포함된 새 상태를 반환합니다. 마찬가지로,ggleTodo 작업을 전달하면 리듀서가 지정된 할 일 항목의 완료 상태를 업데이트합니다.

5단계: 상태 변경 사항 액세스 및 구독

애플리케이션의 현재 상태를 읽으려면 스토어에서 제공하는 getState 메소드를 사용할 수 있습니다. 이 메소드는 Redux 저장소에 저장된 전체 상태 객체를 반환합니다.

console.log(store.getState());
// Output: [{ id: 1621234567890, text: 'Learn Redux', completed: true }, 
//          { id: 1621234567891, text: 'Build an app', completed: false }]

상태를 읽는 것 외에도 구독 메소드를 사용하여 상태 변경 사항을 구독할 수도 있습니다. 이 메서드를 사용하면 상태가 변경될 때마다 콜백 함수를 실행할 수 있으므로 UI를 업데이트하거나 상태 업데이트에 대한 응답으로 다른 부작용을 수행하는 데 유용합니다.

const unsubscribe = store.subscribe(() => {
  console.log('State updated:', store.getState());
});

상태 변경 구독을 완료하면 구독에서 반환된 함수를 호출하여 구독을 취소할 수 있습니다.

unsubscribe();

6단계: Redux를 React 구성 요소에 연결

Redux를 React와 통합하려면 React 구성 요소를 Redux 스토어에 연결해야 합니다. 여기가 Provider, useSelector 및 useDispatch 유틸리티를 제공하는 React-redux 패키지가 작동하는 곳입니다.

Redux 스토어를 prop으로 전달하여 전체 애플리케이션을 Provider 구성 요소로 래핑하는 것부터 시작하세요. 이렇게 하면 React 앱의 모든 구성 요소에서 Redux 스토어를 사용할 수 있습니다.

import React from 'react';
import ReactDOM from 'react-dom';
import { Provider } from 'react-redux';
import { createStore } from 'redux';
import App from './App';
import todoReducer from './reducers';

// Create the Redux store
const store = createStore(todoReducer);

ReactDOM.render(
  <Provider store={store}>
    <App />
  </Provider>,
  document.getElementById('root')
);

다음으로 useSelector 및 useDispatch 후크를 사용하여 구성 요소를 Redux 스토어에 연결합니다. useSelector를 사용하면 상태에 액세스할 수 있고, useDispatch를 사용하면 작업을 디스패치할 수 있습니다.

import React from 'react';
import { useSelector, useDispatch } from 'react-redux';
import { addTodo, toggleTodo } from './actions';

function TodoList() {
  const todos = useSelector(state => state);
  const dispatch = useDispatch();

  const handleAddTodo = (text) => {
    dispatch(addTodo(text));
  };

  const handleToggleTodo = (id) => {
    dispatch(toggleTodo(id));
  };

  return (
    <div>
      <button onClick={() => handleAddTodo('New Todo')}>Add Todo</button>
      <ul>
        {todos.map(todo => (
          <li
            key={todo.id}
            onClick={() => handleToggleTodo(todo.id)}
            style={{ textDecoration: todo.completed ? 'line-through' : 'none' }}
          >
            {todo.text}
          </li>
        ))}
      </ul>
    </div>
  );
}

export default TodoList;

In this example, the TodoList component displays a list of todo items, with the ability to add new items and toggle their completion status. The useSelector hook retrieves the state from the Redux store, while the useDispatch hook allows the component to dispatch actions.

By connecting your React components to Redux in this way, you can ensure that your application's state is managed consistently and predictably.

Best Practices and Common Pitfalls

While Redux is a powerful tool for managing state in complex applications, it also comes with its own set of best practices and potential pitfalls. Understanding these will help you avoid common mistakes and make the most of Redux in your projects.

Best Practices

  • Keep Your State Normalized: In large applications, it's essential to keep your state normalized, meaning that you avoid nesting data too deeply. Instead of storing entire objects within other objects, store only the references (e.g., IDs) and keep the actual objects in a separate, flat structure. This approach simplifies state updates and prevents unnecessary data duplication.
  • Use Action Creators: Action creators are functions that return action objects. They not only make your code more readable but also allow you to modify the structure of actions later without changing the code that dispatches them. Always use action creators instead of directly creating action objects in your components.
  • Use Immutable Update Patterns: Redux relies on immutability, meaning that state objects should never be modified directly. Instead, always return new objects when updating the state in reducers. You can use tools like the spread operator (...) or utility libraries like Immutable.js or Immer to help with this.
  • Keep Reducers Pure: Reducers should be pure functions, meaning that they should only depend on their arguments and not produce side effects, such as modifying external variables or making API calls. This purity ensures that your state changes are predictable and easy to test.
  • Split Your Reducers: As your application grows, so will your state. Instead of having one large reducer that handles everything, split your reducers into smaller, more manageable functions, each responsible for a specific part of the state. Redux provides a combineReducers function to help you merge these smaller reducers into a single root reducer.
  • Use Middleware for Side Effects: Redux is designed to be a synchronous state container, but many applications need to handle asynchronous actions, such as API calls. To manage these side effects, use middleware like redux-thunk or redux-saga, which allows you to handle asynchronous actions in a clean and maintainable way.

Common Pitfalls to Avoid

  • Overusing Redux: Not every piece of state needs to be stored in Redux. While Redux is great for managing application-wide state, it's overkill for local UI state that doesn't need to be shared across components. For example, the state of a dropdown menu or a modal window is better managed with React's built-in useState hook.
  • Mutating State Directly: One of the most common mistakes in Redux is directly mutating the state object in reducers. Doing so can lead to subtle bugs and make your application unpredictable. Always return a new state object instead of modifying the existing one.
  • Putting Everything in One Reducer: While it's possible to manage your entire application's state with a single reducer, doing so will quickly become unmanageable as your application grows. Instead, break down your state into smaller pieces and create a reducer for each piece. Use combineReducers to merge them into a single root reducer.
  • Ignoring the Redux DevTools: Redux DevTools is an invaluable tool for debugging and understanding how your state changes over time. It allows you to inspect every action that is dispatched, view the current state, and even "time travel" by replaying actions. Make sure to integrate Redux DevTools into your development environment.
  • Not Handling Side Effects Properly: Redux is designed to be a synchronous state container, but most applications need to deal with asynchronous actions, such as API calls. If you handle these side effects within reducers or actions, you break the purity of your functions and make your code harder to test and maintain. Instead, use middleware like redux-thunk or redux-saga to manage side effects.

Conclusion and Next Steps

In this comprehensive guide, we've covered the fundamentals of Redux, from its core concepts to setting up and using it in a simple React application. Redux is a powerful tool for managing state in complex applications, but it also comes with its own learning curve and best practices.

저장소, 작업 및 리듀서를 이해하면 애플리케이션 상태를 제어하고 애플리케이션이 예측 가능하고 일관되게 작동하는지 확인할 수 있습니다. 제공된 단계별 가이드를 통해 이제 자신의 프로젝트에 Redux를 설정하고 전문가처럼 상태 관리를 시작할 수 있습니다.

그러나 Redux는 많은 고급 기능과 사용 사례가 포함된 광범위한 주제입니다. 이해를 심화하려면 다음을 살펴보세요.

  • 미들웨어: redux-thunk 및 redux-saga와 같은 미들웨어를 사용하여 비동기 작업과 부작용을 처리하는 방법을 알아보세요.
  • Redux 툴킷: Redux 작업을 보다 쉽고 효율적으로 만들어주는 도구 및 모범 사례 세트인 Redux 툴킷을 사용하여 Redux 개발을 단순화하세요.
  • Redux 애플리케이션 테스트: 리듀서, 액션 및 연결된 구성 요소에 대한 단위 테스트를 작성하는 방법을 살펴보세요.
  • 고급 패턴: 복잡한 상태 형태 처리, 성능 최적화, Redux를 다른 라이브러리와 통합하는 등 고급 Redux 패턴을 알아보세요.
  • 커뮤니티 및 리소스: Redux 커뮤니티에 가입하고, 공식 문서를 읽고, 온라인 튜토리얼과 과정을 탐색하여 계속 학습하세요.

Redux를 마스터하려면 시간과 연습이 필요하다는 점을 기억하세요. 더 많이 사용할수록 더 편안해질 것입니다. 계속 실험하고 계속 학습하세요.

위 내용은 Redux 이해: 초보자를 위한 종합 가이드의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

성명:
본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.