如何将状态传递给react-redux应用程序中的选择器? [英] How is state passed to selectors in a react-redux app?

查看:62
本文介绍了如何将状态传递给react-redux应用程序中的选择器?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我遇到了一个示例,其中mapStateToProps函数正在使用memoization。我只是想知道如何将state参数传递给memoized选择器。在查看重新选择以及redux的文档之后,似乎mapStateToProps可以返回一个接受状态作为其参数的函数,而连接装饰器可能是将状态传递给它但不确定的。有人可以解释一下吗?

I came across an example, where the mapStateToProps function is using memoization. I was just wondering how the "state" parameter is passed onto memoized selectors. After looking at the docs for reselect as well as redux, it seems that the mapStateToProps can return a function which accepts state as its argument, and the connect decorator might be the one passing the state to it but am not sure. Can someone please shed some light?

views / tracklist / index.js

const mapStateToProps = createSelector(
  getBrowserMedia,
  getPlayerIsPlaying,
  getPlayerTrackId,
  getCurrentTracklist,
  getTracksForCurrentTracklist,
  (media, isPlaying, playerTrackId, tracklist, tracks) => ({
    displayLoadingIndicator: tracklist.isPending || tracklist.hasNextPage,
    isMediaLarge: !!media.large,
    isPlaying,
    pause: audio.pause,
    pauseInfiniteScroll: tracklist.isPending || !tracklist.hasNextPage,
    play: audio.play,
    selectedTrackId: playerTrackId,
    tracklistId: tracklist.id,
    tracks
  })
);

export default connect(
  mapStateToProps,
  mapDispatchToProps
)(Tracklist);

core / tracklists / selectors.js

export function getCurrentTracklist(state) {
//  console.log(state);
  let tracklists = getTracklists(state);
  return tracklists.get(tracklists.get('currentTracklistId'));
}

export const getTracksForCurrentTracklist = createSelector(
  getCurrentPage,
  getCurrentTrackIds,
  getTracks,
  (currentPage, trackIds, tracks) => {
    return trackIds
      .slice(0, currentPage * TRACKS_PER_PAGE)
      .map(id => tracks.get(id));
  }
);


推荐答案

状态传递到的概述当我们使用react-redux中的Connect组件时,选择器

什么是选择器?

选择器从源中提取数据子集。

A selector extracts a subset of data from a source.

让我们将Redux存储视为我们的前端数据库。出于此目的在数据库中,如果要提取总数据的子集,则执行查询。以类似的方式选择器是我们对Redux商店的查询。

Let us think of the Redux store as our 'front end database'. For the purposeIn a database if you want to extract a subset of the total data you execute a query. In a similar fashion selectors are our queries to the Redux store.

在最简单的情况下,选择器可以返回整个商店的状态。

In the simplest case, a selector could just return the state of the entire store.

重新选择文档为我们提供了三个很好的理由来使用选择器

The reselect docs give us three great reasons to use selectors


  • 选择器可以计算派生数据,允许Redux存储
    最小可能状态。

  • 选择器效率很高。除非其中一个参数发生变化,否则选择器不会重新计算

  • 选择器是
    可组合的。它们可以用作其他选择器的输入。

什么是高阶组件?

高阶组件是一个获取现有组件并返回新组件的函数。

A higher-order component is a function that takes an existing component and returns a new component.

Connect是给定选择器的高阶组件

取自这个精彩的要点给出了连接的一个很好的解释。

Taken from this brilliant gist which gives a good explanation of connect.


connect()是一个函数将与Redux相关的道具注入您的
组件。

connect() is a function that injects Redux-related props into your component.

Connect是一个更高阶的组件,使我们的React组件了解Redux商店。当我们调用connect时,我们可以传递mapStateToProps和mapDispatchToProps。这些函数定义方式,我们的新组件将连接到redux商店。

Connect is a higher order component that makes our React component know about the Redux store. When we call connect we can pass mapStateToProps and mapDispatchToProps. These functions define the way in which our new component will be connected to the redux store.

我们可以通过传递给它来访问状态mapStateToProps函数作为参数。

We can give it access to state by passing a mapStateToProps function as an argument.

我们还可以通过mapDispatchToProps将动作创建者绑定到store.dispatch。这样做的好处是我们不需要传递整个商店,以便组件可以访问store.dispatch,以便组件可以调度自己的Redux操作。

We can also bind action creators to store.dispatch through mapDispatchToProps. The advantage of this is that we don't need to pass down the entire store in order for a component to have access to store.dispatch so that the component can dispatch its own Redux actions.

我们传递给Connect的mapStateToProps函数是一个选择器

来自react-redux docs

From the react-redux docs


mapStateToProps函数接受整个
Redux商店状态的单个参数,并返回一个要作为props传递的对象。通常称为选择器的是

The mapStateToProps function takes a single argument of the entire Redux store’s state and returns an object to be passed as props. It is often called a selector.

想想mapStateToProps返回的对象是我们查询的结果Redux商店。结果

Think of the object that is returned by mapStateToProps as the result of our query to the Redux store. The resulting


mapStateToProps函数通常应该返回一个普通对象。

The mapStateToProps function should normally return a plain object.

调用mapStateToProps的结果通常是一个普通对象,表示我们从redux商店中提取的数据。

更高阶的Connect组件允许我们通过将来自这个新对象的数据与组件的现有道具合并来扩展现有组件的功能。

The higher order Connect component allows us to extend the functionality of an existing component by merging in the data from this new object with the component's existing props.

由于选择器只是函数,我们也可以使用connect组件将它们连接到Redux商店。

Since selectors are just functions we can connect them to the Redux store using the connect component as well.

但在某些情况下我们可以返回一个函数。我们为什么要这样做?

However in some cases we can return a function. Why would we do this?

通过在mapStateToProps中撤回函数,我们可以劫持组件的渲染周期并优化性能


在需要更多控制渲染
性能的高级场景中,mapStateToProps()也可以返回一个函数。在这个
的情况下,该函数将用作特定
组件实例的mapStateToProps()。这允许你进行每个实例的memoization。

In advanced scenarios where you need more control over the rendering performance, mapStateToProps() can also return a function. In this case, that function will be used as mapStateToProps() for a particular component instance. This allows you to do per-instance memoization.

通过将mapStateToProps函数作为参数传递给我们的高阶组件,我们连接的组件将在Redux商店中的某个状态发生变化时随时更新。

By passing the mapStateToProps function as an argument to our higher order component our connected component will be updated anytime the some state has changed in the Redux store.

如果这些更新频繁发生或状态树很大,那么重选库很有用,因为它允许我们使用 memoized 选择器。

If these updates happen very frequently or the state tree is large then the reselect library is useful as it allows us to use memoized selectors.

这个奇特的单词意味着存储选择器调用的结果,以防需要再次检索它们。

This fancy word means that results of selector calls are stored in case they need to be retrieved again.

因此,如果mapStatesToProps返回一个普通对象而不是函数,那么每当我们的商店状态发生变化时,我们就会为我们的组件提供新的道具。???

So if mapStatesToProps returned a plain object instead of a function then whenever our store state changed then we would have new props for our component.???

连接选择器到商店

如果您使用的是React Redux,您可以在mapStateToProps()中将选择器作为常规函数调用:

If you are using React Redux, you can call selectors as regular functions inside mapStateToProps():

import { getVisibleTodos } from '../selectors'

const mapStateToProps = (state) => {
  return {
    todos: getVisibleTodos(state)
  }
}

在多个组件之间共享选择器

在使用重新选择库时,我们可以像重新选择组件一样重新选择道具。这允许我们跨多个组件共享选择器。

We can give reselect selectors props just like components when using the reselect library. This allows us to share selectors across multiple components.

假设我们有多个toDo列表,每个列表都有自己的Id。我们仍然会为每个toDo列表实例使用相同的getVisibleTodos选择器,但只是传递一个不同的id作为prop。

Say we have multiple toDo lists each with their own Id. We would still use the same getVisibleTodos selector for each toDo list instance but just pass a different id as a prop.

然而,问题是createSelector仅在其参数集与其前一组参数相同时才返回缓存值。

However the issue with this is that createSelector only returns the cached value when its set of arguments is the same as its previous set of arguments.

重新选择文档指出我们可以通过在mapStateToProps中返回一个函数来克服这个限制:

The reselect docs point out that we can overcome this limitation by returning a function inside mapStateToProps:


为了在多个组件之间共享一个选择器并保留
memoization,组件
的每个实例都需要它自己的选择器私有副本。
如果提供给connect的mapStateToProps参数返回一个函数
而不是一个对象,它将用于为容器的每个实例创建一个单独的
mapStateToProps函数。

In order to share a selector across multiple components and retain memoization, each instance of the component needs its own private copy of the selector. If the mapStateToProps argument supplied to connect returns a function instead of an object, it will be used to create an individual mapStateToProps function for each instance of the container.

通过返回mapStateToProps中的函数,我们可以克服这个限制,并且memoization将正常工作。

By returning a function inside mapStateToProps we can overcome this limitation and memoization will work correctly.

For有关更详细的说明,请参阅

For a more detailed explanation see this

这篇关于如何将状态传递给react-redux应用程序中的选择器?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆