フック付きのreact-reduxを使用していますが、小道具ではないパラメーターを受け取るセレクターが必要です。ドキュメントには次のように記載されています
セレクター関数はownProps引数を受け取りません。ただし、小道具はクロージャー(以下の例を参照)またはカレーセレクターを使用して使用できます。
ただし、それらは例を提供していません。ドキュメントに記載されているカレーの適切な方法は何ですか?
これは私がやったことであり、うまくいくようですが、これは正しいですか?関数から関数を返すことによる影響はありuseSelector
ますか(再レンダリングされないように見えますか?)
// selectors
export const getTodoById = state => id => {
let t = state.todo.byId[id];
// add display name to todo object
return { ...t, display: getFancyDisplayName(t) };
};
const getFancyDisplayName = t => `${t.id}: ${t.title}`;
// example component
const TodoComponent = () => {
// get id from react-router in URL
const id = match.params.id && decodeURIComponent(match.params.id);
const todo = useSelector(getTodoById)(id);
return <span>todo.display</span>;
}
セレクターの戻り値が新しい関数の場合、コンポーネントはストアが変更されるたびに常に再レンダリングされます。
useSelector()
===
浅い等式ではなく、デフォルトで厳密な参照等式チェックを使用します
これは、非常に単純なセレクターで確認できます。
const curriedSelector = state => () => 0;
let renders = 0;
const Component = () => {
// Returns a new function each time
// triggers a new render each time
const value = useSelector(curriedSelector)();
return `Value ${value} (render: ${++renders})`;
}
value
が常に0
である場合でも、実際の値を取得するためにuseSelector
関数を呼び出していることを認識していないため、コンポーネントはストアアクションごとに再レンダリングします。
ただし、関数ではなくuseSelector
finalを受け取るようにするとvalue
、コンポーネントは実際のvalue
変更でのみレンダリングされます。
const curriedSelector = state => () => 0;
let renders = 0;
const Component = () => {
// Returns a computed value
// triggers a new render only if the value changed
const value = useSelector(state => curriedSelector(state)());
return `Value ${value} (render: ${++renders})`;
}
結論としては機能しますuseSelector
が、呼び出されるたびに使用されるセレクターから新しい関数(または新しい非プリミティブ)を返すのは非常に非効率的です。
小道具は、クロージャー(以下の例を参照)またはカレーセレクターを使用して使用できます。
ドキュメントは次のいずれかを意味しました。
useSelector(state => state.todos[props.id])
useSelector(state => curriedSelector(state)(props.id))
connect
はいつでも利用できます。セレクターを少し変更すると、両方で機能する可能性があります。
export const getTodoById = (state, { id }) => /* */
const Component = props => {
const todo = useSelector(state => getTodoById(state, props));
}
// or
connect(getTodoById)(Component)
あなたは、セレクタからオブジェクトを返しているので、あなたは、デフォルトの平等のチェックを変更したい場合があるので注意してくださいuseSelector
に浅い平等チェック。
import { shallowEqual } from 'react-redux' export function useShallowEqualSelector(selector) { return useSelector(selector, shallowEqual) }
あるいは単に
const todo = useSelector(state => getTodoById(state, id), shallowEqual);
セレクターでコストのかかる計算を実行している場合、またはデータが深くネストされていてパフォーマンスが問題になる場合は、メモ化を使用するオリヴィエの回答を参照してください。
この記事はインターネットから収集されたものであり、転載の際にはソースを示してください。
侵害の場合は、連絡してください[email protected]
コメントを追加