You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Selectors can compute derived data, allowing Redux to store the minimal possible state.
Selectors are efficient. A selector is not recomputed unless one of its arguments changes.
Selectors are composable. They can be used as input to other selectors.
constmySelector=createSelector(state=>state.values.value1,state=>state.values.value2,(value1,value2)=>value1+value2)// You can also pass an array of selectorsconsttotalSelector=createSelector([state=>state.values.value1,state=>state.values.value2],(value1,value2)=>value1+value2)
In the above example, mapStateToProps calls getVisibleTodos to calculate todos. This works great, but there is a drawback: todos is calculated every time the state tree is updated. If the state tree is large, or the calculation expensive, repeating the calculation on every update may cause performance problems. Reselect can help to avoid these unnecessary recalculations.
We would like to replace getVisibleTodos with a memoized selector that recalculates todos when the value of state.todos or state.visibilityFilter changes, but not when changes occur in other (unrelated) parts of the state tree.
Reselect provides a function createSelector for creating memoized selectors. createSelector takes an array of input-selectors and a transform function as its arguments. If the Redux state tree is mutated in a way that causes the value of an input-selector to change, the selector will call its transform function with the values of the input-selectors as arguments and return the result. If the values of the input-selectors are the same as the previous call to the selector, it will return the previously computed value instead of calling the transform function.
In the example above, getVisibilityFilter and getTodos are input-selectors. They are created as ordinary non-memoized selector functions because they do not transform the data they select. getVisibleTodos on the other hand is a memoized selector. It takes getVisibilityFilter and getTodos as input-selectors, and a transform function that calculates the filtered todos list.
reselect的灵感来自NuclearJS的getter部分。re-frame的subscriptions和speedskater的提议。
我们看看一个Selector可以做什么 ? 一下是官方提到的三个重点。
翻译过来大概就是
如果对文字不感兴趣也可以直接看视频教程。视频讲解了文字部分的所有内容。
上面的说法其实非常抽象。让我们看一个例子
这个例子是计算商品的总税务。如果无法理解的话也不要紧。我们先看看
createSelector
的函数体和官方的描述。createSelector可以接受一个或者一组的inputSelector或者一个inputSelectors作为参数。参数的最后一个总会是一个resultFunc。resultFunc会接收之前的inputSelector参数计算出来的值作为参数。resultFunc是一个回调函数。
使用方法如下
其他还有更高级的说明在后面写下来。
我们现在回头看最早之前的那个demo。现在已经非常明了。createSelector接受inputSelector返回新的inputSelector。感觉就像这样。
所以demo里的所有方法变量都是Selector结尾。最前面的两个Selector是取state里面的状态的,是之后用来做参数用的。后面的这一段调用了createSelector方法。
使用Es6的reduce计算了商品的总价值。因为createSelector允许多个Selector作为参数。所以第二步做了这个。
利用了taxPercentSelector和之前定义的subtotalSelector计算了一波总税务。
最后把商品总价和商品总税务合并起来 算出税后商品价格。整个过程非常清晰明确。
emmmm 虽然很清晰明确 但是也并非是我们利用他的理由。利用reselect并不是为了这样,利用reselect的真正原因会在下面说到。
接下来这里记录怎么用Reselect的selector。
但是你想知道为什么需要reselect,得看这里。
reselect提供的是带有记忆(缓存)能力的Selector。为了展示这一点。我们会用一个最基本的todo例子说明。这个例子取自基于最基础的redux todo list example。
containers/VisibleTodoList.js
上面的例子
mapStateToProps
调用了getVisibleTodos
去计算todos
。这工作起来非常的棒。但是有缺点:当每次状态树改变的时候todos
都会被重新计算(不相关的状态改变也会触发)。如果状态树很庞大或者计算一次的代价非常昂贵。如果是这样每次重新计算会带来性能问题。Reselect可以帮助你避免掉不必要的重计算。那么接下来我们将会使用Reselect来改造这个简单的todo demo。
我们要把之前的
getVisibleTodos
替换成一个有记忆(缓存)能力的Selector这个Selector重计算只会发生在state.todos
或者state.visibilityFilter
改变的时候。其他不相关的状态改变都不会触发重计算。Reselect提供了
createSelector
方法创建一个可记忆(缓存)的Selector。这个方法以一组Selector函数和一个转换函数(前面提到的resultFunc)作为参数。如果Redux状态树通过突变的方式导致input-selector变化了。那么selector将会调用transfrom方法并把input-selector作为参数再返回结果。如果input-selector的和之前的调用用到的input-selector一样的话。selector将会返回之前计算出来的结果而不是调用transform方法。好了好了 让我们来定义一个可记忆(缓存)的selector并且取名叫做
getVisibleTodos
去替换之前没有用可记忆(缓存)的版本吧 :selectors/index.js
是的这个例子和前面的大同小异。只是参数的位置有点不一样其他都大同小异。但是真的运行的时候区别还是蛮大的。
在上面的例子中。
getVisibilityFilter
和getTodos
都算是input-selector。最后一个参数是一个箭头函数。这个参数被认为是transfrom方法。Reselect会在状态改变的时候调用它过滤todo列表。The text was updated successfully, but these errors were encountered: