redux、react的连接

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/cjg214/article/details/83240512

建议先了解:redux【博文:redux浅谈】

例子:使用react与redux编写一个计数器。

  • 使用react组件渲染页面,两个按钮一个展示
  • 将计数器数值托管到redux中;提供+1和-1两个action来更新状态
  • 将redux中的state、发起action的方法通过属性传递到组件中;并将state渲染为数值;将两个方法注册到按钮的点击事件中
  • 渲染组件,并在state被更新时重新渲染。

一、redux与react手动连接

ReactDOM.render(
  <Counter
    value={Store.getState()}
    onIncrement={() => { store.dispatch({ type: "INCREMENT" }) }
    onDecrement={() => { store.dispatch({ type: "DECREMENT" }) }
  />,
  oRoot
)

缺点:

  • 无法给子组件传递state和方法
  • 任意state的变化,会导致整个状态树的重新渲染。

二、采用react-redux(推荐)

点评:可以给组件树中任一组件绑定state和方法,还进行了性能优化,避免不必要的渲染。

步骤:

(1)首先安装,

npm i react-redux -S

在所有组件的顶层,使用provider组件给整个程序提供store。

index.js

import { Provider } from "react-redux";

...

ReactDOM.render(
  <Provider store={store}>
  </Provider>
)

(2)共有多种写法

第一种

connect()的第一个参数是一个函数,它将state.counter传给组件counter属性。

connect()的第二个参数是个对象,是所有action创建函数的集合。将所有的action创建函数传到了组件的同名属性。同时为每一个action创建函数隐式绑定了dispatch方法,因此可以在react组件内直接通过this.props调用这些action创建函数。

// container.js

import * as ActionCreators from "../actions";

export default connect(
  state => ({counter:state.counter}),
  ActionCreators
)(Counter)

第二种

connect()第二个参数是参数为dispatch的函数,该函数返回的对象也会被合并到组建的props中。备注:因为该方法不会为action创建函数绑定dispatch方法,所以需要手动绑定。

点评:有几个action创建函数,在connect()里就要分发多少次,麻烦~

container.js

export default connect(
  state => ({ counter: state.counter }),
  dispatch => ({
    increment: () => { dispatch(increment()) }
  })
)(Counter)

// increment为一个action创建函数

第三种

connect()第二个参数为dispatch函数,但是函数的返回值采用bindActionCreators来减少代码。

container.js

import * as ActionCreators from "../actions";
import { bindActionCreators } from "redux";

export default connect(
  state => ({ counter: state.counter }),
  dispatch => bindActionCreators(ActionsCreators, dispatch)
)(Counter)

第四种

在组件内发起action构造函数,进而connect()的第二个参数为空

点评:耦合度高,比较麻烦

container.js

function Counter({ counter, dispatch }) {
  return (
    <p>
      <button onClick={() => { dispatch(INCREMENT()) }}></button>
    </p>
  )
}

Counter.propTypes={
  counter:propTypes.number.isRequired,
}

export default connect(
  state => ({ counter: state.counter }),
)(Counter)

第五种

装饰器写法。将connect()写在组件类声明上面。注意:若采用装饰器写法,就不能使用无状态函数来编写组件。因为装饰器添加在类声明上面。

同时,必须使用static propTypes={}这种静态属性的写法,来声明props类型。

container.js

import * as ActionCreators from "../actions";

@connect(
  state=>({counter:state.counter}),
  ActionCreators
);

class Counter extends React.Component{
  static propTypes={
    counter:propTypes.number.isRequired,
  }

  render(){
    ....
  }
}

Ps:推荐书籍《react开发实例精解》脸谱书

猜你喜欢

转载自blog.csdn.net/cjg214/article/details/83240512