Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

redux 中 dispatch 一个 action 的几种写法 #2

Open
hacker0limbo opened this issue Aug 24, 2019 · 0 comments
Open

redux 中 dispatch 一个 action 的几种写法 #2

hacker0limbo opened this issue Aug 24, 2019 · 0 comments
Labels
react react 笔记整理 redux redux 笔记整理

Comments

@hacker0limbo
Copy link
Owner

hacker0limbo commented Aug 24, 2019

以下代码均以计数器为例.

方法一

connect方法不加第二个参数, 默认会将dispatch传入至组件的props

// drecement 是一个 action creator
const decrement = (id) => {
  return {
    type: "DECREMENT",
    id
  }
}

const App = props => {
  const { counter, dispatch } = props

  return (
    <div>
      <span></span>
      <button onClick={() => dispatch({ type: "INCREMENT" })}></button>
      <button onClick={() => dispatch(decrement(1))}></button>
    </div>
  )
}

const mapStateToProps = state => {
  return {
    counter: state.counter
  }
}

export default connect(mapStateToProps)(App)

方法二

使用mapDispatchToProps, 此时dispatch方法不会再被传入到组件的props中, 取而代之的传入的是一个对象(类似mapStateToProps), 对象里面包含所有可以 dispatch一个action的函数

// drecement 是一个 action creator
const decrement = id => {
  return {
    type: "DECREMENT",
    id
  }
}

const App = props => {
  const { counter, increment, decrement } = props

  return (
    <div>
      <span></span>
      <button onClick={() => increment()}></button>
      <button onClick={() => decrement(1)}></button>
    </div>
  )
}

const mapStateToProps = state => {
  return {
    counter: state.counter
  }
}

const mapDispatchToProps = dispatch => {
  return {
    increment: () => dispatch({ type: "INCREMENT" }),
    decrement: (id) => dispatch(decrement(id))
  }
}

export default connect(mapStateToProps, mapDispatchToProps)(App)

方法三

使用bindAcionCreator, 相比方法二, 无需编写一系列函数.

注意, 需要将action写成action creator形式, 即函数形式

import { bindAcionCreator } from 'redux'

const increment = () => {
  return {
    type: "INCREMENT",
  }
}

// drecement 是一个 action creator
const decrement = id => {
  return {
    type: "DECREMENT",
    id
  }
}

const App = props => {
  const { counter, increment, decrement } = props

  return (
    <div>
      <span></span>
      <button onClick={() => increment()}></button>
      <button onClick={() => decrement(1)}></button>
    </div>
  )
}

const mapStateToProps = state => {
  return {
    counter: state.counter
  }
}

const mapDispatchToProps = dispatch => {
  return bindActionCreator({ increment, decrement }, dispatch)
}

export default connect(mapStateToProps, mapDispatchToProps)(App)

方法四(推荐)

mapDispatchToProps定义为一个对象

const increment = () => {
  return {
    type: "INCREMENT",
    id
  }
}

// drecement 是一个 action creator
const decrement = id => {
  return {
    type: "DECREMENT",
    id
  }
}

const App = props => {
  const { counter, increment, decrement } = props

  return (
    <div>
      <span></span>
      <button onClick={() => increment()}></button>
      <button onClick={() => decrement(1)}></button>
    </div>
  )
}

const mapStateToProps = state => {
  return {
    counter: state.counter
  }
}

export default connect(mapStateToProps, { increment, decrement })(App)

方法五(推荐)

方法四存在的问题是, 如果有很多action creator, 那么写起来不会很方便, 此时结合方法三里的bindAcionCreator可以一次性导入

稍微提一下bindAcionCreator, 接受两个参数:

  1. 一个函数(一个 action creator), 或者一个对象, 每个元素对应一个action creator
  2. dispatch
// actions.js

export const decrement = id => {
  return {
    type: "DECREMENT",
    id
  }
}

// drecement 是一个 action creator
export const decrement = id => {
  return {
    type: "DECREMENT",
    id
  }
}
import { bindAcionCreator } from 'redux'
import * as types from './actions'

const App = props => {
  const { counter, increment, decrement } = props

  return (
    <div>
      <span></span>
      <button onClick={() => increment()}></button>
      <button onClick={() => decrement(1)}></button>
    </div>
  )
}

const mapStateToProps = state => {
  return {
    counter: state.counter
  }
}

const mapDispatchToProps = dispatch => {
  return bindActionCreator(types, dispatch)
}

export default connect(mapStateToProps, mapDispatchToProps)(App)

方法六

在方法五的基础上, 使用装饰器@connect, 此方法需要开启babel

// actions.js

export const decrement = id => {
  return {
    type: "DECREMENT",
    id
  }
}

// drecement 是一个 action creator
export const decrement = id => {
  return {
    type: "DECREMENT",
    id
  }
}
import { bindAcionCreator } from 'redux'
import * as types from './actions'

const mapStateToProps = state => {
  return {
    counter: state.counter
  }
}

const mapDispatchToProps = dispatch => {
  return bindAcionCreator(types, dispatch)
}

@connect(mapStateToProps, mapDispatchToProps)
class App extends Component {
  render() {
    const { counter, increment, decrement } = this.props

    return (
      <div>
        <span></span>
        <button onClick={() => increment()}></button>
        <button onClick={() => decrement(1)}></button>
      </div>
    )
  }
}

总结

自己常用的主要是 4 和 5. 当然肯定是存在别的更加优雅的写法, 也欢迎在评论里和我交流

参考

@hacker0limbo hacker0limbo added redux redux 笔记整理 生活 个人的想法, 生活感悟等 react react 笔记整理 and removed 生活 个人的想法, 生活感悟等 labels Aug 24, 2019
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
react react 笔记整理 redux redux 笔记整理
Projects
None yet
Development

No branches or pull requests

1 participant