mapDispatchToProps 란 무엇입니까?


358

Redux 라이브러리에 대한 설명서를 읽었으며 다음 예제가 있습니다.

상태를 읽는 것 외에도 컨테이너 구성 요소는 작업을 전달할 수 있습니다. 비슷한 방식으로, 메소드 mapDispatchToProps()를 수신 dispatch()하고 프리젠 테이션 컴포넌트에 삽입하려는 콜백 소품을 리턴 하는 함수를 정의 할 수 있습니다 .

이것은 실제로 의미가 없습니다. mapDispatchToProps이미 가지고있을 때 왜 필요한 mapStateToProps가요?

또한이 편리한 코드 샘플을 제공합니다.

const mapDispatchToProps = (dispatch) => {
  return {
    onTodoClick: (id) => {
      dispatch(toggleTodo(id))
    }
  }
}

누군가이 기능이 무엇이며 왜 유용한 지 평신도의 용어로 설명해 주시겠습니까?

답변:


577

왜 mapDispatchToProps유용한 정보 가 결정화되지 않은 것 같습니다 .

이것은 실제로 container-component패턴 의 맥락에서만 대답 할 수 있습니다. 먼저 컨테이너 구성 요소 를 사용한 다음 React와 함께 사용하면 가장 잘 이해할 수 있습니다.

간단히 말해서, 당신 components은 물건을 표시하는 것에 만 관심이 있어야합니다. 들이 정보를 얻기 위해 가정되는 유일한 장소는 소품이다 .

"재료 표시"(구성 요소)와 분리 된 것은 다음과 같습니다.

  • 물건을 표시하는 방법,
  • 이벤트 처리 방법

그게 다야 containers.

따라서 component패턴 의 "잘 설계된" 은 다음과 같습니다.

class FancyAlerter extends Component {
    sendAlert = () => {
        this.props.sendTheAlert()
    }

    render() {
        <div>
          <h1>Today's Fancy Alert is {this.props.fancyInfo}</h1>
          <Button onClick={sendAlert}/>
        </div>
     }
}

이 구성 요소가 props (을 통해 redux store에서 가져온)에서 표시하는 정보를 가져 오는 방법 mapStateToProps과 props에서 조치 기능을 얻는 방법을 참조하십시오 sendTheAlert().

그 위치 mapDispatchToProps는 다음과 같습니다.container

// FancyButtonContainer.js

function mapDispatchToProps(dispatch) {
    return({
        sendTheAlert: () => {dispatch(ALERT_ACTION)}
    })
}

function mapStateToProps(state) {
    return({fancyInfo: "Fancy this:" + state.currentFunnyString})
}

export const FancyButtonContainer = connect(
    mapStateToProps, mapDispatchToProps)(
    FancyAlerter
)

당신이 볼 수 있을지는의 지금, 궁금해 container 1 REDUX 파견 및 저장 및 상태와 ... 물건에 대해 알고있다.

는 component패턴에서 FancyAlerter, 렌더링은 그 물건의에 대해 알 필요가 없다 않는 : 그것은에서 호출의 방법을 얻을 수 onClick의 소품을 통해 버튼의.

그리고 ... mapDispatchToPropsredux가 컨테이너가 그 기능을 소품의 포장 된 구성 요소로 쉽게 전달할 수 있도록하는 유용한 수단이었습니다.

이 모든 것은 문서의 todo 예제와 비슷하며 여기에 또 다른 대답이 있지만 패턴을 고려하여 이유 를 강조하려고 시도했습니다 .

(참고 : 내부에 액세스 할 수없는 기본적인 이유 mapStateToProps와 동일한 목적으로 사용할 수 없으므로 래핑 된 구성 요소에 사용하는 메서드를 제공하는 데 사용할 수 없습니다 . mapDispatchToPropsdispatchmapStateToPropmapStateToPropsdispatch

왜 그들이 두 개의 매핑 함수로 나누려고했는지 모르겠습니다 mapToProps(state, dispatch, props) .


1 컨테이너 FancyButtonContainer를 "사물"로 강조하기 위해 의도적으로 명시 적으로 컨테이너 이름을 지정했습니다 .

export default connect(...) ⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀

대부분의 예제에 표시되는 구문


5
여전히 알고 싶습니다. 구성 요소 내에서 store.dispatch를 직접 호출하여 필요한 기능을 처리 할 수없는 것은 무엇입니까?
— pixelpax

8
@ user2130130 없음. 좋은 디자인에 관한 것입니다. 구성 요소를 store.dispatch에 결합 한 경우 redux를 제외하거나 redxu 기반이 아닌 다른 장소 (또는 지금 생각할 수없는 다른 곳)를 사용하려고하면 많은 변화. 귀하의 질문은 "우리가 왜 '좋은 설계 관행'을 귀찮게 하는가-동일한 기능을 가지지 만 코딩하는 것"으로 일반화됩니다. mapDispatchToProps가 제공되어 잘 디자인되고 완전히 분리 된 구성 요소를 작성할 수 있습니다.
— GreenAsJade

4
내가 실제로 여기에 얻지 못하는 것은 무엇입니까 : ALERT_ACTION액션 함수 또는 액션 함수 type에서 반환되는 것입니까? : / so baffed
— Jamie Hutber

1
@JamieHutber 엄격하게, ALERT_ACTION은이 질문과 아무 관련이 없습니다. 그것은 파견에 대한 유효한 인수이며, 내 코드에서 설명 된 것처럼 redux.js.org/docs/api/Store.html#dispatch 와 같이 파견에서 사용하는 객체를 반환하는 "액션 빌더"에서 나옵니다. . 여기서 중요한 점은 디스패치 호출 방법이 컨테이너에 설명되어 있으며 구성 요소 소품에 전달된다는 것입니다. 구성 요소는 다른 곳에서는 소품에서만 기능을 가져옵니다. 이 패턴에서이를 수행하는 "잘못된"방법은 구성 요소에 디스패치를 ​​전달하고 구성 요소에서 동일한 호출을하는 것입니다.
— GreenAsJade

1
하위 컴포넌트에 소품으로 전달해야하는 여러 개의 조치 작성기가있는 경우, 한 가지 대안은 mapDispatchToProps 내의 bindActionCreators로 랩 작성하는 것입니다 (redux.js.org/docs/api/bindActionCreators.html 참조) . ); 또 다른 대안은 단순히 connect ()에 액션 생성자 (예 : connect (mapStateToProps, {actioncreators}))를 제공하는 것입니다.
— dave

81

기본적으로 속기입니다. 따라서 글을 쓰는 대신

this.props.dispatch(toggleTodo(id));

예제 코드에 표시된대로 mapDispatchToProps를 사용하고 다음과 같이 작성하십시오.

this.props.onTodoClick(id);

또는이 경우 이벤트 처리기로 사용합니다.

<MyComponent onClick={this.props.onTodoClick} />

여기에 Dan Abramov의 유용한 비디오가 있습니다 : https://egghead.io/lessons/javascript-redux-generating-containers-with-connect-from-react-redux-visibletodolist


감사합니다. 또한 디스패치가 처음에 소품에 어떻게 추가됩니까?
— 코드 위스퍼러

14
자체 mapDispatch기능을 제공하지 않으면 Redux는 기본값을 사용합니다. 이 기본 mapDispatch함수는 단순히 dispatch함수 참조 를 가져 와서로 제공합니다 this.props.dispatch.
— markerikson

7
디스패치 방법에 의해 아래로 전달되는 제공자 구성 요소
— 디에고 하즈을

55

mapStateToProps()구성 요소가 다른 일부 구성 요소에 의해 업데이트되는 상태를 업데이트하는 데 도움이되는 유틸리티이며,
mapDispatchToProps()구성 요소가 작업 이벤트를 발생시키는 데 도움이되는 유틸리티입니다 (응용 프로그램 상태 변경을 유발할 수있는 작업 디스패치)


23

mapStateToProps, mapDispatchToProps과 connect에서 react-redux라이브러리에 액세스 할 수있는 편리한 방법 제공 state및 dispatch상점의 기능을. 따라서 기본적으로 connect는 고차 구성 요소이므로 이것이 의미가 있다면 래퍼로 생각할 수도 있습니다. 따라서 state변경 mapStateToProps될 때마다 새로운 것으로 호출 state되고 나중에 props구성 요소 를 업데이트하면 렌더링 기능을 실행하여 브라우저에서 구성 요소를 렌더링합니다. mapDispatchToProps또한 props구성 요소 에 키-값을 저장 하며 일반적으로 함수 형태를 취합니다. 이러한 방식으로 state구성 요소에서 변경을 트리거 할 수 있습니다 onClick.onChange 이벤트를.

문서에서 :

const TodoListComponent = ({ todos, onTodoClick }) => (
  <ul>
    {todos.map(todo =>
      <Todo
        key={todo.id}
        {...todo}
        onClick={() => onTodoClick(todo.id)}
      />
    )}
  </ul>
)

const mapStateToProps = (state) => {
  return {
    todos: getVisibleTodos(state.todos, state.visibilityFilter)
  }
}

const mapDispatchToProps = (dispatch) => {
  return {
    onTodoClick: (id) => {
      dispatch(toggleTodo(id))
    }
  }
}

function toggleTodo(index) {
  return { type: TOGGLE_TODO, index }
}

const TodoList = connect(
  mapStateToProps,
  mapDispatchToProps
)(TodoList) 

또한 React Stateless 기능 및 상위 주문 구성 요소에 익숙해야합니다.


파견은 기본적으로 이벤트와 같은가요?
— 코드 위스퍼러

2
이벤트와 관련이있을 수 있습니다. 디스패치 는 단지 함수 이며 응용 프로그램 상태 를 변경하는 유일한 방법 입니다. mapStateToProps 는 상점 의 디스패치 기능 을 React Component 에 노출시키는 한 가지 방법 입니다. 또한 connect는 redux 의 일부가 아니라는 사실은 react-redux 라고 불리는 리액터 및 redux로 작동하는 상용구 및 상용구 감소 라이브러리 입니다. 루트 반응 구성 요소에서 하위 반응으로 상점 을 전달하면 react-redux 없이 동일한 결과를 얻을 수 있습니다 .
— Vlad Filimon

3

mapStateToProps수신 state및 props당신이 구성 요소에 전달할 상태에서 소품을 추출 할 수 있습니다.

mapDispatchToPropsdispatch그리고 받는 props함수는 액션 생성자를 디스패치하여 결과 함수를 실행할 때 액션이 디스패치되도록합니다.

나는 이것이 당신이 dispatch(actionCreator())당신의 구성 요소 내에서해야 할 일을 덜어 주므로 조금 더 읽기 쉽습니다.

https://github.com/reactjs/react-redux/blob/master/docs/api.md#arguments


감사하지만 dispatch방법 의 가치는 무엇 입니까? 그거 어디서 났어?
— 코드 위스퍼러

오. 디스패치는 기본적으로 작업이 redux / flux 단방향 흐름을 시작하게합니다. 다른 답변은 이것보다 귀하의 질문에 더 나은 것으로 보입니다.
— Harry Moreno

또한 디스패치 방법은 <Provider/>자체적으로 개선 된 기능에서 비롯 됩니다. 자식 구성 요소에서 디스패치를 ​​사용할 수 있도록 자체 고차 구성 요소 마법을 수행합니다.
— Ricardo Magalhães

3

이제 다음과 같이 redux에 대한 조치가 있다고 가정하십시오.

export function addTodo(text) {
  return {
    type: ADD_TODO,
    text
  }
}

가져 오면

import {addTodo} from './actions';

class Greeting extends React.Component {

    handleOnClick = () => {
        this.props.onTodoClick(); // This prop acts as key to callback prop for mapDispatchToProps
    }

    render() {
        return <button onClick={this.handleOnClick}>Hello Redux</button>;
    }
}

const mapDispatchToProps = dispatch => {
    return {
      onTodoClick: () => { // handles onTodoClick prop's call here
        dispatch(addTodo())
      }
    }
}

export default connect(
    null,
    mapDispatchToProps
)(Greeting);

함수 이름에서 알 수 있듯이 액션을 props (우리 컴포넌트의 props)에 mapDispatchToProps()매핑dispatch

따라서 prop onTodoClick은 mapDispatchToPropsaction을 파견하기 위해 위임 하는 기능 의 열쇠 addTodo입니다.

또한 코드를 자르고 수동 구현을 우회하려면이 작업을 수행 할 수 있습니다.

import {addTodo} from './actions';
class Greeting extends React.Component {

    handleOnClick = () => {
        this.props.addTodo();
    }

    render() {
        return <button onClick={this.handleOnClick}>Hello Redux</button>;
    }
}

export default connect(
    null,
    {addTodo}
)(Greeting);

정확히 의미하는 것은

const mapDispatchToProps = dispatch => {
    return {
      addTodo: () => { 
        dispatch(addTodo())
      }
    }
}
당사 사이트를 사용함과 동시에 당사의 쿠키 정책과 개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.