gpt4 book ai didi

javascript - 如何通过 react-redux 的 useSelector 钩子(Hook)正确使用柯里化(Currying)的选择器函数?

转载 作者:搜寻专家 更新时间:2023-11-01 05:27:18 25 4
gpt4 key购买 nike

我正在使用带钩子(Hook)的 react-redux,我需要一个选择器,它接受一个不是 prop 的参数。 documentation

The selector function does not receive an ownProps argument. However, props can be used through closure (see the examples below) or by using a curried selector.

但是,他们没有提供示例。如文档中所述, curry 的正确方法是什么?

这就是我所做的并且似乎有效,但这是对的吗?从 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>;
}

最佳答案

When the return value of a selector is a new function, the component will always re-render on each store change.

useSelector() uses strict === reference equality checks by default, not shallow equality

您可以使用一个 super 简单的选择器来验证这一点:

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收到最后的 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 一起使用的选择器返回新函数(或任何新的非 primitives )效率极低每次调用它。

props can be used through closure (see the examples below) or by using a curried selector.

文档意味着:

  • 关闭useSelector(state => state.todos[props.id])
  • curry 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 的默认相等性检查。到 shallow equality check .

import { shallowEqual } from 'react-redux'

export function useShallowEqualSelector(selector) {
return useSelector(selector, shallowEqual)
}

或者只是

const todo = useSelector(state => getTodoById(state, id), shallowEqual);

如果您在选择器中执行昂贵的计算或者数据嵌套很深并且性能成为问题,请查看 Olivier's answer which uses memoization .

关于javascript - 如何通过 react-redux 的 useSelector 钩子(Hook)正确使用柯里化(Currying)的选择器函数?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57464286/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com