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, mapDispatchToPropsconnect에서 react-redux라이브러리에 액세스 할 수있는 편리한 방법 제공 statedispatch상점의 기능을. 따라서 기본적으로 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수신 stateprops당신이 구성 요소에 전달할 상태에서 소품을 추출 할 수 있습니다.

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 onTodoClickmapDispatchToPropsaction을 파견하기 위해 위임 하는 기능 의 열쇠 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.