연결이 있는 전역 상태 만들기

6562 단어 react
몇 년 전 React 생태계에서 처음 개발을 시작했을 때 저는 Redux, Flow, MobX 등 도구를 포함한 응용 프로그램 상태 관리Flux pattern의 개념을 소개했습니다.나는 Redux로 한동안 개발했고, 그것을 매우 좋아했으며, 심지어는 node에서 작성된 두 개의 상태기 프로그램을 지원했다. 이것은 React나 전단과 아무런 관계가 없다.
통량 모델의 핵심 원칙은 다음과 같다.
  • 응용 프로그램에서 발생한 일은 하나의 구성 요소가 알고 있는 것이 아니라 하나의 실제 출처일 뿐이다.
  • 어플리케이션 상태는 사용자가 UI에 대해 특정 작업을 수행하는 동안에만 변경해야 합니다(또는 데이터가 추출될 때에만 변경해야 합니다. 그러나 이는 대개 초기 작업의 결과 때문입니다).
  • 작업은 상태를 직접 갱신할 수 없지만 갱신 상태를 포함하는 모든 논리를 포함하는 중앙 어음 교환소에 파견해야 한다.
  • 기본적으로, 모든 구성 요소는 그곳에 가서 정보를 얻을 수 있고, 모든 구성 요소는 그곳에 가서 작업이 수행되었다고 말할 수 있다.Redux는 "Reducer 함수"를 통해 이 모드를 실현합니다.작업을 할당할 때마다 이 함수를 실행합니다. 이 함수는 두 개의 인자가 있습니다. 현재 상태와 이 동작을 정의하는 대상입니다. 이 함수를 사용하여 새로운 상태를 만들고 전체 프로그램의 새로운 실제 원본이 됩니다.
    설령 그것을 사용할 때 약간의 도전에 부딪히더라도 나는 이런 모델을 좋아한다.React 어셈블리의 렌더링 기능은 모 어셈블리에서 전달된 도구가 변경될 때만 시작됩니다.그들 스스로는 탐지기를 고의로 다른 곳에 저장된 응용 프로그램 상태로 설정할 수 없다.전역 상태가 변경되면 변경 사항이 애플리케이션의 UI에 자동으로 반영되는 것은 아니며 이는 거의 모든 목적에 어긋납니다.
    신속하고 더러운 해결 방안은 응용 프로그램의 상태를 응용 프로그램의 루트 구성 요소에 유지하고 가능한 한 속성 값 (스케줄링 작업에 필요한 리셋 속성) 을 전달하는 것이다.문제는 응용 프로그램에서 어떤 유형의 복잡성에 부딪히면 대량의 도구를 통해 조작하기 어려워지고 테스트에 큰 장애가 된다는 것이다.구성 요소에 이름 있는 파라미터를 대량으로 보냅니다. 체인을 따라 잎 구성 요소가 실제 필요로 하는 모든 구성 요소로 전달할 수 있도록 하기 위해서입니다.이것은 그다지 좋지 않은 코드 맛으로 통상적으로 prop drilling라고 불린다.
    Redux는 창설connected components을 통해 이 문제를 해결했다.전역 상태나 스케줄러에 접근하고자 하는 모든 구성 요소는 프레임워크에서 제공하는 connect 함수에 봉인될 수 있습니다.
    엔진 뚜껑 아래에서, 이것은 작성한 구성 요소를 다른 구성 요소와 함께 포장합니다. Redux 전역 상태를 가리키는 특수 구독 링크를 포함합니다.이것은 하위 단계 (하위 집합) 에 상태와 스케줄링에 대한 접근 권한을 제공합니다. 전통적인 도구로서 변경 사항이 발생할 때 다시 렌더링을 터치합니다.결국 다음과 같이 여러 구성 요소가 있습니다.
    const MyButton = (props) => {
      return (
        <button onClick={props.toggleButton}>
          { props.active ? "On" : "Off" }
        </button>
      )
    }
    
    const mapStateToProps = (state) => ({
      buttonIsActive: state.buttonIsActive
    })
    
    const mapDispatchToProps = (dispatch) => {
      toggleButton: () => dispatch({ type: "click_button" })
    }
    
    export default connect(mapStateToProps, mapDispatchToProps)(MyButton)
    
    2019년 초에 발표된React Hooks은 개발 모델에 대한 개념을 많이 바꾸었고 구성 요소는 갑자기 더욱 쉽고 뚜렷하게 자신을 이해하게 되었다.버튼 하나만 독립적으로 켜기/끄기 상태이면 여러 파일의 구조와 프레임워크별 솔루션을 갑자기 다음과 같은 내용으로 교체할 수 있습니다.
    const [active, setActive] = React.useState(true)
    
    문제는 복잡성이다.Flux 모드의 가장 큰 장점은 간단한 조작은 그와 상호작용할 수 있는 모든 구성 요소로 스케줄링할 수 있고 업데이트가 필요한 내용과 위치를 알 필요가 없다는 것이다.프로그램 상태에 관심이 있는 사람은 프로그램 상태의 업데이트에 반응해야 한다.useState 항상 포함된 모든 것에 좋은 것이지만, 그 외에 통량 패턴이 최초로 유행했던 축소 문제로 돌아가기 시작한다.
    그러나 우리는 React가 제공하는 흔치 않은 두 개의 갈고리를 사용하여 전역 응용 프로그램 상태와 스케줄러를 구축하여 단일한 진상 출처와 React가 이렇게 유용한 동태를 재현할 수 있다.
    먼저 만나요useReducer.만약 useState 에 익숙하다면, 현재 상태 값과setter 함수를 되돌려 주는 두 값 그룹의 호출 모드를 알 수 있습니다.useReducer는 같은 패턴을 가지고 있지만 간단한 값을 사용하지 않고 Redux 스타일의 Reducer 함수를 사용하여 복잡한 응용 프로그램 상태와 스케줄러를 되돌려 업데이트 상태를 조작합니다.
    이것은 간단한 단일 조작 축소기 함수 예시입니다. 우리는 잠시 후에 초기 상태 값을 사용할 것입니다.만약 네가 Redux를 쓴 적이 있다면, 그것은 보기에 매우 익숙해 보일 것이다.
    // contexts/User/reducer.js
    
    export const reducer = (state, action) => {
      switch (action.type) {
        case "toggle_button":
          return {
            ...state,
            active: !state.active
          }
    
        default:
          return state
      }
    }
    
    export const initialState = {
      active: false
    }
    
    모든 React 구성 요소에서 개별적으로 이 기능을 사용하여 감속기 기능의 전원 공급 상태를 생성할 수 있지만 이 구성 요소에만 해당됩니다.
    const [state, dispatch] = React.useReducer(reducer, initialState)
    
    전 세계적으로 제품을 제공하기 위해서 우리는 그것을 useContext와 배합해야 한다.Context는 후크스보다 조금 일찍 리액트에 도입된 개념이다.약간의 작업을 통해 도구를 필요로 하는 후대 부품에 전달하는 대체 방법을 제공할 수 있으며, 도구가 필요하지 않은 후대 부품을 뛰어넘을 수 있다.
    최초 릴리즈에서는 도구가 제공되고 그 범위 내에서 리셋 도구가 실행되는 상위 구성 요소 두 개와 손자 구성 요소가 변경되면 다시 렌더링되는 상위 구성 요소를 설정합니다.후자의 문법은...때로는 어색할 때도 있었지만 다행히 연결useContext을 제공해 소비자들이 더욱 쉽게 사용할 수 있게 했다.
    다음 코드 예시에서, 우리는 앞의 코드에서 우리의 Reducer 함수와 초기 상태를 가져올 것이다.그리고 구성 요소를 만들고 내보냅니다.
  • reducer 함수로 응용 프로그램 상태와 스케줄링을 만들고 유지한 다음
  • Provider 호출(자체는 갈고리가 아님)으로 생성된 더 높은 단계React.createContext 구성 요소를 되돌려줍니다.그것은 수조 형식으로 상태와 분배를 value 도구로 고급 구성 요소에 전달한다.
  • // contexts/User/index.jsx
    
    import React from "react"
    import { reducer, initialState } from "./reducer"
    
    export const UserContext = React.createContext({
      state: initialState,
      dispatch: () => null
    })
    
    export const UserProvider = ({ children }) => {
      const [state, dispatch] = React.useReducer(reducer, initialState)
    
      return (
        <UserContext.Provider value={[state, dispatch]}>
            { children }
        </UserContext.Provider>
      )
    }
    
    걱정하지 마라. 이것은 절대로 가장 어려운 부분이다. 이것은 통용되는 모델로, 우리의 각 감속기 기능의 수요에 독립해야 한다.
    다음 단계는 공급자 구성 요소에 프로그램 전체를 포장하는 것입니다.이것은 매우 흔히 볼 수 있는 외관이다.
    // components/App.jsx
    
    import { UserProvider } from "../contexts/UserProvider"
    
    // Some other components you've written for your app...
    import Header from "./Header"
    import Main from "./Main"
    
    export default () => {
      return (
        <UserProvider>
          <Header />
          <Main />
        </UserProvider>
      )
    }
    
    마지막으로 전역 상태 및/또는 할당 함수에 액세스하려는 모든 구성 요소는 컨텍스트를 가져오고 useContext 훅에서 참조해야 합니다.
    // components/MyButton.jsx
    
    import React from "react"
    import { UserContext } from "../contexts/User"
    
    export default () => {
      const [state, dispatch] = React.useContext(UserContext)
    
      return (
        <button onClick={() => dispatch({ type: "toggle_button" })}>
          { state.active ? "On" : "Off" }  
        </button>
      )
    }
    
    이로 인해 발생한 두 값 수조는 state 호출에 대한 전역dispatchuseReducer의 인용으로 분해됩니다. 이것은 우리가 상하문에 프로그램 구성 요소 구조value 속성을 제공하는 수조의 방식이기 때문입니다.이렇게!
    모든 구성 요소가 이 상하문을 사용할 수 있으며, 그 중 어떤 구성 요소가 보낸, 상태를 바꾸는 스케줄링 작업은 모든 구성 요소를 적절하게 업데이트할 수 있습니다.추가 상태 속성과 조작 형식을 사용하여 Reducer 함수를 쉽게 업데이트할 수 있습니다.

    좋은 웹페이지 즐겨찾기