react-redux@7.1用于hooks的API

React-redux 7.1发版啦。

因为在新的项目中用到了hooks,但是用的时候react-redux还处于alpha.x版本的状态。用不了最新的API,感觉不是很美妙。好在,这两天发布了7.1版本。

现在来看看怎么用这个新的API。

useSelector()

const result : any = useSelector(selector : Function, equalityFn? : Function)

这个是干啥的呢?就是从redux的store对象中提取数据(state)。

注意: 因为这个可能在任何时候执行多次,所以你要保持这个selector是一个纯函数。

这个selector方法类似于之前的connect的mapStateToProps参数的概念。并且useSelector会订阅store, 当action被dispatched的时候,会运行selector。

当然,仅仅是概念和mapStateToProps相似,但是肯定有不同的地方,看看selector和mapStateToProps的一些差异:

  • selector会返回任何值作为结果,并不仅仅是对象了。然后这个selector返回的结果,就会作为useSelector的返回结果。
  • 当action被dispatched的时候,useSelector()将对前一个selector结果值和当前结果值进行浅比较。如果不同,那么就会被re-render。 反之亦然。
  • selector不会接收ownProps参数,但是,可以通过闭包(下面有示例)或使用柯里化selector来使用props。
  • 使用记忆(memoizing) selector时必须格外小心(下面有示例)。
  • useSelector()默认使用===(严格相等)进行相等性检查,而不是浅相等(==)。

你可能在一个组件内调用useSelector多次,但是对useSelector()的每个调用都会创建redux store的单个订阅。由于react-reduxv7版本使用的react的批量(batching)更新行为,造成同个组件中,多次useSelector返回的值只会re-render一次。

相等比较和更新

当函数组件渲染时,会调用提供的selector函数,并且从useSelector返回其结果。(如果selector运行且没有更改,则会返回缓存的结果)。

上面有说到,只当对比结果不同的时候会被re-render。从v7.1.0-alpha.5开始,默认比较是严格比较(===)。这点于connect的时候不同,connect使用的是浅比较。这对如何使用useSelector()有几个影响。

使用mapState,所有单个属性都在组合对象中返回。返回的对象是否是新的引用并不重要 - connect()只比较各个字段。使用useSelector就不行了,默认情况下是,如果每次返回一个新对象将始终进行强制re-render。如果要从store中获取多个值,那你可以这样做:

  • useSelector()调用多次,每次返回一个字段值。

  • 使用Reselect或类似的库创建一个记忆化(memoized) selector,它在一个对象中返回多个值,但只在其中一个值发生更改时才返回一个新对象。

  • 使用react-redux 提供的shallowEqual函数作为useSelectorequalityFn参数。

就像下面这样:

import {
    shallowEqual, useSelector } from 'react-redux'

// later
const selectedData = useSelector(selectorReturningObject, shallowEqual)

useSelector 例子

上面做了一些基本的阐述,下面该用一些例子来加深理解。

基本用法

import React from 'react'
import {
    useSelector } from 'react-redux'

export const CounterComponent = () => {
   
  const counter = useSelector(state => state.counter)
  return <div>{
   counter}</div>
}

通过闭包使用props来确定要提取的内容:

import React from 'react'
import {
    useSelector } from 'react-redux'

export const TodoListItem = props => {
   
  const todo = useSelector(state => state.todos[props.id])
  return
  • 4
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值