bindActionCreators(actionCreators, dispatch)

값이 액션 생산자인 객체를 받아서, 같은 키를 가지지만 각각의 생산자들을 dispatch로 감싸서 바로 호출 가능하게 만든 객체로 바꿉니다.

보통은 Store 인스턴스에서 바로 dispatch를 호출하면 됩니다. Redux를 React와 함께 사용한다면, react-reduxdispatch 함수를 함께 제공하므로 바로 호출할 수 있습니다.

bindActionCreators의 유일한 사용처는, Redux를 상관하지 않는 컴포넌트로 액션 생산자를 넘기지만 dispatch나 Redux 스토어는 넘기고 싶지 않을 때입니다.

편의상 첫 번째 인수로 함수를 넘겼다가 함수를 반환 받을 수도 있습니다.

인자

  1. actionCreators (Function or Object): 액션 생산자 또는 값으로 액션 생산자들을 가지는 객체.

  2. dispatch (Function): Store 인스턴스에서 가져온 dispatch 함수.

반환

(Function or Object): 원래의 객체를 모사하지만 각각의 함수가 원래의 액션 생산자가 반환하는 액션을 바로 디스패치하는 객체. 만약 actionCreators로 함수를 넘겼다면, 반환값 역시 함수가 됩니다.

예시

TodoActionCreators.js

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

export function removeTodo(id) {
  return {
    type: 'REMOVE_TODO',
    id
  }
}

SomeComponent.js

import { Component } from 'react'
import { bindActionCreators } from 'redux'
import { connect } from 'react-redux'

import * as TodoActionCreators from './TodoActionCreators'
console.log(TodoActionCreators)
// {
//   addTodo: Function,
//   removeTodo: Function
// }

class TodoListContainer extends Component {
  componentDidMount() {
    // Injected by react-redux:
    let { dispatch } = this.props

    // Note: this won't work:
    // TodoActionCreators.addTodo('Use Redux')

    // You're just calling a function that creates an action.
    // You must dispatch the action, too!

    // This will work:
    let action = TodoActionCreators.addTodo('Use Redux')
    dispatch(action)
  }

  render() {
    // Injected by react-redux:
    let { todos, dispatch } = this.props

    // Here's a good use case for bindActionCreators:
    // You want a child component to be completely unaware of Redux.

    let boundActionCreators = bindActionCreators(TodoActionCreators, dispatch)
    console.log(boundActionCreators)
    // {
    //   addTodo: Function,
    //   removeTodo: Function
    // }

    return (
      <TodoList todos={todos}
                {...boundActionCreators} />
    )

    // An alternative to bindActionCreators is to pass
    // just the dispatch function down, but then your child component
    // needs to import action creators and know about them.

    // return <TodoList todos={todos} dispatch={dispatch} />
  }
}

export default connect(
  state => ({ todos: state.todos })
)(TodoListContainer)

  • 왜 전통적인 Flux처럼 액션 생산자를 스토어 인스턴스에 바로 바인드하지 않는지 물을 수도 있습니다. 문제는 그 방법이 서버에서 랜더해야 하는 유니버설 앱에서는 잘 작동하지 않는다는겁니다. 보통은 매 요청마다 서로 다른 데이터로 스토어 인스턴스를 준비해야 하지만, 액션 생산자를 선언 중에 바인드하면 모든 요청에 대해 하나의 스토어 인스턴스 밖에 쓸 수 없습니다.

  • ES5를 사용한다면 import * as 대신 require('./TodoActionCreators')bindActionCreators의 첫번째 인수로 넘기면 됩니다. 모듈 시스템과는 상관 없이 actionCreators의 인수 값이 함수이기만 하면 됩니다.

results matching ""

    powered by

    No results matching ""