私はこれに従おうとしています 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にどのように適合するかを説明できますか?
getUser
はレデューサーではなく、実際にはセレクターです。つまり、ストアから特定のデータを抽出する方法を知っている関数です。
セレクター店舗構造を変更した場合、users
が突然state.entities.users
代わりにstate.users.objects.entities
(または何でも)必要なのは、getUser
セレクターを更新するだけで、古い場所への参照を作成していたアプリ内のすべての場所ではありません。
Reduxストアのリファクタリングに関しては、特に便利です。
セレクタは、redux状態のゲッターです。ゲッターと同様に、セレクターは状態の構造をカプセル化し、再利用可能です。セレクタは、派生プロパティを計算することもできます。
Redux-sagaで見たようなセレクターを書くことができます。例えば:
const getUsersNumber = ({ users }) => users.length;
const getUsersIds = ({ users }) => users.map(({ id }) => id);
等...
reselect を使用することもできます。これはReduxの単純な「セレクタ」ライブラリで、セレクタをメモしてより効率的にします。
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/
セレクターは、Reduxの状態を引数として受け取り、コンポーネントに渡すデータを返す関数です。
const getUserData = state => state.user.data;
なぜそれを使用する必要がありますか?
reselect を使用すると、同じ入力が関数に渡されたときにデータの意味をメモするのに役立ち、再計算するのではなく前の結果を返します。これにより、アプリケーションのパフォーマンスが向上します。