web-dev-qa-db-ja.com

reduxのセレクターとは何ですか?

私はこれに従おうとしています code in redux-saga

export const getUser = (state, login) => state.entities.users[login]
export const getRepo = (state, fullName) => state.entities.repos[fullName]

これは this のようなサガで使用されます:

import { getUser } from '../reducers/selectors'

// load user unless it is cached
function* loadUser(login, requiredFields) {
  const user = yield select(getUser, login)
  if (!user || requiredFields.some(key => !user.hasOwnProperty(key))) {
    yield call(fetchUser, login)
  }
}

このgetUserレデューサー(レデューサーであっても)は、レデューサーが通常期待するものとは非常に異なって見えます。

誰がセレクターとは何か、getUserがレデューサーであり、redux-sagaにどのように適合するかを説明できますか?

42
dagda1

getUserはレデューサーではなく、実際にはセレクターです。つまり、ストアから特定のデータを抽出する方法を知っている関数です。

セレクター店舗構造を変更した場合、usersが突然state.entities.users代わりにstate.users.objects.entities(または何でも)必要なのは、getUserセレクターを更新するだけで、古い場所への参照を作成していたアプリ内のすべての場所ではありません。

Reduxストアのリファクタリングに関しては、特に便利です。

61
horyd

セレクタは、redux状態のゲッターです。ゲッターと同様に、セレクターは状態の構造をカプセル化し、再利用可能です。セレクタは、派生プロパティを計算することもできます。

Redux-sagaで見たようなセレクターを書くことができます。例えば:

const getUsersNumber = ({ users }) => users.length;

const getUsersIds = ({ users }) => users.map(({ id }) => id);

等...

reselect を使用することもできます。これはReduxの単純な「セレクタ」ライブラリで、セレクタをメモしてより効率的にします。

13
Ori Drori
function mapStateToProps (state) {
    return {
        user: state.user,
    }
}

initialState of reducer by user store
const initialState = {
  isAdmin:false,
  isAuth:false,
  access:[1,2,5]
};

class AppComp extends React.Component{
render(){
        const {user: { access:access}} = this.props;
        const Rand = Math.floor(Math.random()*4000)
        return (<div>
            {`APP ${Rand} `}
    <input type="button" defaultValue="change auth" onClick={this.onChangeUserAuth} />
        <p>TOTAL STATUS COUNT IS {access.length}</p>
        </div>)
    }
}}

ただし、セレクターを使用できます

var getUser = function(state) {
    return state.user
}


const getAuthProp = createSelector(
    getUser,
    (user) => user.access
);


function mapStateToProps (state) {
    return {
       // user: state.user,
        access: getAuthProp(state)
    }
}

主な問題は、このコンポーネントがすべてのユーザーを使用することです:state.userとユーザーの変更(etc isAdmin、isAuth、access)は、このストアの一部のみを必要とするこのコンポーネントを再レンダリングします-アクセス!!!

Reduxでは、アプリケーション内のどこかでアクションが呼び出されるたびに、マウントおよび接続されているすべてのコンポーネントがmapStateToProps関数を呼び出します。これが、Reselectが素晴らしい理由です。何も変更がなければ、メモされた結果を返すだけです。

現実の世界では、多くの場合、複数のコンポーネントで状態オブジェクトの同じ特定の部分が必要になります。

https://medium.com/@parkerdan/react-reselect-and-redux-b34017f8194c

Reselectが提供するcreateSelector関数は、以前のセレクターからセレクターを派生させる最も基本的な方法を実装します。最も単純な使用例は、単一の他のセレクターからセレクターを派生させることです。この場合、createSelectorのパラメーターは、入力セレクターと、そのセレクターの結果を新しいセレクターの結果に変換する関数です。例えば

var getProducts = function(state) {
    return state.products
}


import {getProducts} from '../app/selectors'
import {createSelector} from 'reselect'

export const getProductTitles = createSelector(
    getProducts,
    (products) => products.map((product) => product.get('title'))
)

これは(メモ化を無視する)と同等です:

import {getProducts} from '../app/selectors'

export const getProductTitles = (state) => {
    return getProducts(state).map((product) => product.get('title'))
}

CreateSelector関数は、複数のセレクターからのデータと単一のセレクターからのデータを結合できます。 createSelectorには任意の数のセレクターを渡すことができ、それらの結果は最終引数として渡される関数に渡されます。 (やや不自然な)例:

const isInCheckout = createSelector(
    getIsShippingPage,
    getIsBillingPage,
    getIsConfirmationPage,
    (isShipping, isBilling, isConfirmation) =>
        isShipping || isBilling || isConfirmation
)

と同等です

const isInCheckout = (state) => {
    return (
        getIsShippingPage(state) ||
        getIsBilingPage(state) ||
        getIsConfirmationPage(state)
    )
}

セレクタを使用してmapStateToProps関数を記述するときの一般的なパターンは、特定のセレクタの結果を格納する各キーを持つオブジェクトを返すことです。 ReselectのcreateStructuredSelectorヘルパー関数を使用すると、最小限の定型文でこのパターンを記述できます。たとえば、私たちが書いた場合

const mapStateToProps = createStructuredSelector({
    title: getProductTitle,
    price: getProductPrice,
    image: getProductImage
})

それは同等です

const mapStateToProps = (state) => {
    return {
        title: getProductTitle(state),
        price: getProductPrice(state),
        image: getProductImage(state)
    }
}

https://docs.mobify.com/progressive-web/0.15.0/guides/reselect/

2
zloctb

セレクターは、R​​eduxの状態を引数として受け取り、コンポーネントに渡すデータを返す関数です。

const getUserData = state => state.user.data;

なぜそれを使用する必要がありますか?

  1. 主な理由の1つは、Reduxでの重複データの回避です。
  2. データオブジェクトの形状は、関連するすべてのコンポーネントに変更を加えるのではなく、アプリケーションの成長に応じて変化し続けます。データを1か所で変更することをお勧め/簡単にします。
  3. セレクターは同じ状態で動作するため、リデューサーに近い必要があります。データの同期が簡単になります。

reselect を使用すると、同じ入力が関数に渡されたときにデータの意味をメモするのに役立ち、再計算するのではなく前の結果を返します。これにより、アプリケーションのパフォーマンスが向上します。

2
CodeZombie