Redux#6フィードバック-冗長連動部品例

19712 ワード

  • 今回のリリースでは、reduceを使用するときにコンポーネントをどのように分割するか、containerコンポーネントでreduceを使用する方法、コンポーネントがUIにのみ集中していることを示し、propsで必要なデータを取得することによって興味のあるコンテンツを分離する方法について説明します.
  • 次の例は、数値をinputに調整するとdiff値が変化し、+、-をクリックすると値が変化する例です.
  • presentational component
    素子
  • は、propsとして必要な値と関数のみを受け入れる
  • container component
    コンポーネント
  • 、アクションの送信または照会に使用

    1. presentational component


    components/Counter.js
    import React from 'react';
    
    export default function Counter({ number, diff, onIncrease, onDecrease, onSetDiff }) {
      const onChange = e => {
        onSetDiff(parseInt(e.target.value), 10); // 기본적으로 input의 value는 string이다. 그래서 변환 필요.
      };
    
      return (
        <div>
          <h1>{number}</h1>
          <div>
            <input type='number' value={diff} onChange={onChange} />;
            <button onClick={onIncrease}>+</button>
            <button onClick={onDecrease}>-</button>
          </div>
        </div>
      );
    }

    2. container component

  • ユーザー・セレクタがステータスを表示します.
    stateは、現在のreduceの状態で何をロードするかを決定し、非構造化割当てとして取り出します.
  • usDispatchを使用すると、dispatchが有効になります.
    関数を作成します.関数が実行されると、アクションがdispatchされます.
  • container/CounterContainer.js
    import React from 'react';
    import Counter from '../components/Counter';
    // 상태를 조회하기 위해 useSelector 사용
    // 액션을 dispatch하기 위해 useDispatch 사용
    import { useSelector, useDispatch } from 'react-redux';
    import { increase, decrease, setDiff } from '../modules/counter';
    
    export default function CounterContainer() {
      const { number, diff } = useSelector(state => ({
        // state에는 state.getState()한 것과 같은 값이 들어있다.
        number: state.counter.number, // number에는 state -> counter 안에 있는 number를 넣어주겠다.
        diff: state.counter.diff,
      }));
      // useSelector의 결과물이 두 가지를 선택한 객체가 된다.
      // 그래서 number, diff만 남는 객체가 되고 비구조화할당으로 두 가지를 꺼내온 것이다.
      // 👏 즉, 꺼내올 값들을 useSelector를 이용해서 객체의 키로 지정해주고 비구조화할당으로 꺼낸 것.
    
      //--------
      const dispatch = useDispatch();
      const onIncrease = () => {
        dispatch(increase());
      };
      const onDecrease = () => {
        dispatch(decrease());
      };
      const onSetDiff = diff => {
        dispatch(setDiff(diff));
      };
    
      return (
        <Counter
          number={number}
          diff={diff}
          onIncrease={onIncrease}
          onDecrease={onDecrease}
          onSetDiff={onSetDiff}
        />
      );
    }
    App.js
    前回リリースしたindexプロバイダでjsに包み、storeを渡した.
    import CounterContainer from './containers/CounterContainer';
    
    function App() {
      return (
        <div className='App'>
          <CounterContainer />
        </div>
      );
    }
    
    export default App;

    整理する



    コンテナとプレゼンテーション構成部品を別々に作成すると、プレゼンテーション構成部品を再利用できます.これは、注目点を分離できるため、非常に有用なモードです.リデスの創始者はこのモデルを公開した.△2019年は別々にできるが、必ずしもそうしなければならないとは限らない.しかし、多くのプロジェクトはこのように行われている.ベロフ特大人は、フォルダを分けていないが、コンテナと専門家を区別して働いていると話した.
    次に、以前の位置決め参照コードを示します.上記のコードを分析するときは、参照用に配置します.
    modules/counter.js
    // 액션 타입 선언
    const SET_DIFF = 'counter/SET_DIFF';
    const INCREASE = 'counter/INCREASE';
    const DECREASE = 'counter/DECREASE';
    
    const initialState = {
      number: 0,
      diff: 1,
    };
    
    // 액션 생성 함수
    export const setDiff = diff => ({ type: SET_DIFF, diff });
    export const increase = () => ({ type: INCREASE });
    export const decrease = () => ({ type: DECREASE });
    
    // reducer
    export default function counter(state = initialState, action) {
      switch (action.type) {
        case INCREASE:
          return {
            ...state,
            number: state.number + state.diff,
          };
        case DECREASE:
          return {
            ...state,
            number: state.number - state.diff,
          };
        case SET_DIFF:
          return {
            ...state,
            diff: action.diff,
          };
        default:
          return state;
      }
    }
    modules/index.js
      import { combineReducers } from 'redux';
    import counter from './counter';
    import todos from './todos';
    
    const reducer = combineReducers({ counter, todos });
    export default reducer;