React 연결 상태만 관리

작성자 Ovie Okeh✏️
Hooks API는 React 응용 프로그램을 작성하고 사고하는 새로운 방식을 가져왔다.지금까지 제가 가장 좋아하는 연결 중 하나는 useReducer 입니다. 복잡한 상태 업데이트를 처리할 수 있습니다. 이것이 바로 저희가 본고에서 소개할 내용입니다.
대형 React 응용 프로그램의 공유 상태를 관리하려면 일반적으로 Redux와 MobX 같은 제3자 라이브러리를 도입해야 한다.이러한 제3자 라이브러리는 더욱 쉽게 예측 가능하고 세분화된 방식으로 응용 프로그램의 상태를 업데이트할 수 있지만, 통상적으로 추가 비용과 학습 곡선을 가져올 수 있다.
좋은 소식은 useReducer 때문에, 당신은 현재 추가 소프트웨어 패키지와 학습 곡선이 없는 상황에서 같은 장점을 얻을 수 있다는 것이다. 그래, 아마도 아주 작은 곡선일 것이다.본고가 끝날 때, 당신은 예측 가능한 방식으로 응용 프로그램의 상태를 관리할 수 있어야 하며, 어떠한 제3자 소프트웨어 패키지도 필요하지 않습니다.

Note: This is not an article bashing Redux, MobX, or any other state management package. They all have cases where they shine. This article simply aims to familiarize you with useReducer and how you can use it as an alternative to manage an application’s state.



use Reducer란 무엇입니까?


공유 상태를 관리하는 방법useReducer을 배우기 전에 이를 더욱 잘 이해하기 위해 해체해야 한다.
이것은 새로운 맞춤형 연결로 현재 첨부되어 있습니다React since v16.8.일부 작업을 스케줄링할 때 구성 요소의 일부 상태를 업데이트할 수 있습니다. 이것은 Redux의 작업 방식과 매우 유사합니다.
이것은 Reducer 함수와 초기 상태를 매개 변수로 하고 상태 변수와 스케줄링 함수를 제공하여 상태를 업데이트할 수 있도록 합니다.만약 Redux가 감축기와 조작을 통해 저장소를 업데이트하는 방법에 익숙하다면, useReducer 의 작업 원리를 이미 알고 있습니다.

use Reducer는 어떻게 작동합니까?


AuseReducer는 초기 상태와 감속기 함수 두 가지가 필요합니다.우리는 아래에서 그것들의 외관을 본 후에 그것들의 각자의 용도를 상세하게 설명할 것이다.
다음 코드 세션을 고려합니다.
// we have to define the initial state of the component's state
const initialState = { count: 0 }

// this function will determine how the state is updated
function reducer(state, action) {
  switch(action.type) {
    case 'INCREMENT':
      return { count: state.count + 1 }
    case 'DECREMENT':
      return { count: state.count - 1 }
    case 'REPLACE':
      return { count: action.newCount }
    case 'RESET':
      return { count: 0 }
    default:
      return state
  }
}

// inside your component, initialize your state like so
const [state, dispatch] = useReducer(reducer, initialState);
위의 코드 세션에서, 우리는 구성 요소에 대한 초기 상태인 스케줄링에 따라 이 상태를 업데이트하는 Reducer 함수를 정의하고, 21줄에서 구성 요소의 상태를 초기화합니다.
Redux를 사용해 본 적이 없는 사람들에게는 모든 것을 분해해 봅시다.

initialState 변수


이것은 구성 요소를 처음 설치할 때 구성 요소 상태의 기본값입니다.

감속기 기능


우리는 일부 작업이 발생할 때 구성 요소의 상태를 업데이트하기를 희망합니다.이 함수는 동작에 따라 포함해야 할 내용을 지정합니다.객체를 반환하고 상태를 대체하는 데 사용됩니다.
여기에는 stateaction 두 개의 매개변수가 있습니다.state는 응용 프로그램의 현재 상태이고 action는 현재 발생하는 조작 세부 사항을 포함하는 대상이다.그것은 보통 동작이 무엇인지를 나타내는 type: 를 포함한다.action 더 많은 데이터를 포함할 수 있으며, 이러한 데이터는 통상적으로 상태에서 업데이트할 새로운 값이다.
작업은 다음과 같습니다.
const replaceAction = {
  type: 'REPLACE',
  newCount: 42,
}
우리의reducer 함수를 돌이켜보면 switch 문장 검사action.type의 값을 볼 수 있습니다.만약 우리가 replaceAction 을 현재 동작으로 우리에게 전달하는 Reducer라면, Reducer는 구성 요소의 상태를 바꾸는 데 사용할 대상 { count: 42 } 을 되돌려줍니다.

스케줄링 작업


우리는 감속기가 현재 무엇인지, 그리고 어떻게 스케줄링 동작을 통해 구성 요소의 다음 상태를 확정하는지 안다.그러나 우리는 어떻게 이런 행동을 취합니까?
코드 세그먼트를 되돌려주고 21줄을 검사합니다.useReducer 이 한 그룹에서 두 개의 값을 되돌려 주는 것을 알 수 있습니다.첫 번째는 상태 대상, 두 번째는 dispatch 함수입니다.이것은 우리가 동작을 조절하는 데 쓰는 것이다.
예를 들어 위에서 정의한 replaceAction 스케줄링을 원한다면 다음과 같이 합니다.
dispatch(replaceAction)

// or

dispatch({
  type: 'REPLACE',
  newCount: 42,
})
분파는 하나의 함수에 불과하다. 자바스크립트의 함수는 일등 공민이기 때문에 우리는 도구를 통해 그것들을 다른 구성 요소에 전달할 수 있다.이것이 바로 응용 프로그램에서 Redux를 대체할 수 있는 이유입니다.

useReducer로 Redux 교체


지금, 이 때문에, 너는 실제로 이 문장을 읽고 있다.당신은 어떻게 이 모든 것을 사용해서 Redux에서 벗어날 수 있습니까?
좋습니다. 구성 요소의 상태를 업데이트하기 위해 동작을 조정하는 방법을 알고 있습니다. 이제 루트 구성 요소의 상태는 Redux 저장소로 대체될 장면을 보려고 합니다.
스토어의 초기 상태를 정의합니다.
const initialState = {
  user: null,
  permissions: [],
  isAuthenticating: false,
  authError: null,
}
현재 우리의 감속기 기능:
function reducer(state, action) {
  switch(action.type) {
    case 'AUTH_BEGIN':
      return {
        ...state,
        isAuthenticating: true,
      }

    case 'AUTH_SUCCESS':
      return {
        isAuthenticating: false,
        user: action.user,
        permissions: action.permissions
        authError: null,
      }

    case 'AUTH_FAILURE':
      return {
        isAuthenticating: false,
        user: null,
        permissions: []
        authError: action.error,
      }

    default:
      return state
  }
}
마지막은 우리의 뿌리 구성 요소다.이것은 저장하고 필요한 데이터와 스케줄링 함수를 필요한 구성 요소에 전달합니다.따라서 서브어셈블리가 필요에 따라 스토리지를 읽고 업데이트할 수 있습니다.
코드의 모양을 살펴보겠습니다.
function App() {
  const [store, dispatch] = useReducer(initialState)

  return (
    <React.Fragment>
      <Navbar user={store.user} />
      <LoginPage store={store} dispatch={dispatch} />
      <Dashboard user={store.user} />
      <SettingsPage permissions={store.permissions} />
    </React.Fragment>
  )
}
우리는 저장소를 처리하기 위해 useReducer 를 설치했는데, 이것이 바로 우리가 저장 값을 서브어셈블리에 전달하는 곳이다.만약 우리가 Redux를 사용한다면, 우리는 App 모든 구성 요소를 포장하고, 단독 저장소를 만들고, 저장소에 연결해야 하는 모든 구성 요소에 대해 Provider 로 포장해야 한다.
그러나 이런 방법을 통해 우리는 모든 샘플 파일을 돌려 저장 값을 도구로 구성 요소에 전달할 수 있다.우리는 필요에 따라 가능한 한 많은 저장, 복원, 초기 상태 등을 가질 수 있으며, Redux를 도입할 필요가 없다.
좋습니다. 로그인 함수를 작성해서 connect 구성 요소에서 호출한 다음에 상점이 어떻게 업데이트되는지 관찰합시다.
async function loginRequest(userDetails, dispatch) {
  try {
    dispatch({ type: 'AUTH_BEGIN' })
    const { data: { user, permissions } } = await axios.post(url, userDetails)
    dispatch({ type: 'AUTH_SUCCESS', user, permissions }) 
  } catch(error) {
    dispatch({ type: 'AUTH_FAILURE', error: error.response.data.message })
  }
}
우리는 <LoginPage /> 구성 요소에서 이렇게 사용합니다.
function LoginPage(props) {
  // ...omitted for brevity
  const handleFormSubmit = async (event) => {
    event.preventDefault()

    await loginRequest(userDetails, props.dispatch)
    const { authError } = props.store
    authError
      ? handleErrors(authError)
      : handleSuccess()
  }
  // ...omitted for brevity
}
우리는 현재 다른 몇 개의 구성 요소에서 읽은 저장 변수를 업데이트할 수 있다.감속기가 동작으로 확정된 새로운 상태로 돌아오면 이 구성 요소들은 새 값LoginPageuser을 얻게 됩니다.
이것은 서로 다른 구성 요소 간에 동적 데이터를 공유하고 코드가 템플릿 파일의 영향을 받지 않고 상대적으로 간단하게 유지되는 매우 모듈화된 방식이다.스토리지 및 스케줄링 기능은 다른 구성 요소에 수동으로 전달할 필요 없이 permissions Hook 을 사용하여 모든 구성 요소에 사용할 수 있습니다.

주의사항


만약 우리가 객관적이라면, 우리는 useContext의 상당히 중요한 한계성을 이야기해야 한다.이러한 제한은 응용 프로그램의 모든 상태를 관리하는 데 방해가 될 수 있습니다.

스토리지 제한 사항


너의 상점은 결코 진정한 글로벌화가 아니다.Redux가 전역 저장소에 대한 실현은 저장소 자체가 어떠한 구성 요소와도 연결되지 않는다는 것을 의미한다.그것은 당신의 응용 프로그램과 분리되어 있습니다.useReducer에서 얻은 상태는 구성 요소와 스케줄링 함수에 달려 있습니다.이것은 서로 다른 감속기에서 한 번 useReducer 호출된 스케줄링을 사용할 수 없게 한다.예를 들어, 두 개의 개별 상점과 배송 기능을 예로 들 수 있습니다.
const [notificationStore, dispatch1] = useReducer(initialState, notificationReducer)
const [authStore, dispatch2] = useReducer(initialState, authReducer)
스케줄링 함수는 되돌아오는 useReducer 호출에 의존하기 때문에 useReducer 에서 useReducer 트리거 상태 업데이트를 사용할 수 없고, dispatch1 에서 authStore 트리거 상태 업데이트를 사용할 수 없습니다.
이런 제한은 어떤 스케줄러 함수가 어떤 감속기에 속하는지 수동으로 추적해야 한다는 것을 의미하며, 결국은 더 많은 팽창을 초래할 수 있다.본문을 작성할 때 스케줄링 함수나 감축기를 조합하는 방법은 아직 알려지지 않았다.

확장성


내가 가장 좋아하는 Redux 기능 중 하나는 확장성이다.예를 들어, 모든 스케줄링 작업을 기록하기 위해 레코더 중간부품을 추가할 수 있으며, Chrome 확장을 사용하여 저장소를 볼 수도 있고, 스케줄링 사이의 변경 사항을 구분할 수도 있습니다.
만약 당신이 dispatch2로 Redux를 교체하기로 결정한다면, 이것들은 모두 당신이 포기할 것입니다.또는 직접 수행할 수 있지만 Redux에서 가져온 템플릿 파일을 다시 가져옵니다.

결론

notificationStore 갈고리는 React 라이브러리에 좋은 추가입니다.이것은 더욱 예측 가능하고 조직적인 방식으로 구성 요소의 상태를 업데이트할 수 있으며, 어느 정도 (useContext와 결합하여 사용할 때) 구성 요소 간의 데이터 공유를 더욱 쉽게 할 수 있다.
그것 또한 그것의 결점이 있다. 우리는 위에서 토론한 적이 있다. 만약 당신이 이러한 결점을 해결할 효과적인 방법을 찾을 수 있다면, 아래의 평론 부분에서 나에게 알려 주십시오.
React documentation to learn more about this와 현재 사용할 수 있는 다른 연결고리를 확인해 보세요.즐거운 인코딩!
편집자: 이 문장에 무슨 문제가 있습니까?정확한 버전here을 찾을 수 있습니다.

플러그인: 네트워크 어플리케이션용 DVR용 LogRocket


 

 
LogRocket는 프런트엔드 로그 기록 도구로 자신의 브라우저에서처럼 문제를 재생할 수 있다.LogRocket은 오류가 발생한 원인을 추측하거나 화면 캡처와 로그 저장을 물어보지 않고 세션을 다시 재생할 수 있도록 합니다.프레임워크가 어떻든지 간에 모든 응용 프로그램과 완벽하게 어울릴 수 있으며, 플러그인은 Redux, Vuex, @ngrx/store의 추가 상하문을 기록합니다.
 
LogRocket은 Redux 작업과 상태를 기록하는 것 외에도 콘솔 로그, JavaScript 오류, 스택 추적, 헤더+본문이 있는 네트워크 요청/응답, 브라우저 메타데이터와 사용자 정의 로그를 기록합니다.또한 DOM은 페이지의 HTML과 CSS를 기록하여 가장 복잡한 단일 페이지 응용 프로그램이라도 픽셀 수준의 비디오를 재구성합니다.
 
Try it for free .
게시물State management using only React Hooks이 먼저 LogRocket Blog에 올라왔다.

좋은 웹페이지 즐겨찾기