The React-Redux documentation provides this example表示何时在多个组件实例中使用选择器并取决于组件的prop。
public String signUp(@RequestBody Usermodel user) {
if(userRepository.findByUsername(user.getUsername())==null) {
userRepository.save(user);
return "Success";
}
else{
return "Username Already Exsist";
}
}
在函数import React, { useMemo } from 'react'
import { useSelector } from 'react-redux'
import { createSelector } from 'reselect'
const makeNumOfTodosWithIsDoneSelector = () =>
createSelector(
state => state.todos,
(_, isDone) => isDone,
(todos, isDone) => todos.filter(todo => todo.isDone === isDone).length
)
export const TodoCounterForIsDoneValue = ({ isDone }) => {
const selectNumOfTodosWithIsDone = useMemo(
makeNumOfTodosWithIsDoneSelector,
[]
)
const numOfTodosWithIsDoneValue = useSelector(state =>
selectNumOfTodosWithIsDone(state, isDone)
)
return <div>{numOfTodosWithIsDoneValue}</div>
}
export const App = () => {
return (
<>
<span>Number of done todos:</span>
<TodoCounterForIsDoneValue isDone={true} />
<span>Number of unfinished todos:</span>
<TodoCounterForIsDoneValue isDone={false} />
</>
)
}
中,为什么作者用TodoCounterForIsDoneValue
包装makeNumOfTodosWithIsDoneSelector
?我对useMemo
中的createSelector
的理解是,它会生成一个记住的选择器,那么“双重”记住该选择器的目的是什么?
答案 0 :(得分:3)
因为每个组件都需要其自己的选择器实例才能实现正确的备注行为。如果许多组件使用相同的选择器实例,并且每个组件使用各自不同的参数(例如selectThingById(state, props.itemId)
),则选择器永远不会记住正确的信息。通过为每个组件创建一个唯一的实例,每个选择器可以传递其自己的单独的arg并获得一致的备注。
答案 1 :(得分:0)
与问题稍微无关,但我认为在这种情况下,我们可以使用 useCallback
来获得相同的结果,而无需在 makeNumOfTodosWithIsDoneSelector
中添加额外的函数层。
import React, { useCallback } from 'react'
import { useSelector } from 'react-redux'
import { createSelector } from 'reselect'
const makeNumOfTodosWithIsDoneSelector =
createSelector(
state => state.todos,
(_, isDone) => isDone,
(todos, isDone) => todos.filter(todo => todo.isDone === isDone).length
)
export const TodoCounterForIsDoneValue = ({ isDone }) => {
const selectNumOfTodosWithIsDone = useCallback(
makeNumOfTodosWithIsDoneSelector,
[]
)
const numOfTodosWithIsDoneValue = useSelector(state =>
selectNumOfTodosWithIsDone(state, isDone)
)
return <div>{numOfTodosWithIsDoneValue}</div>
}
export const App = () => {
return (
<>
<span>Number of done todos:</span>
<TodoCounterForIsDoneValue isDone={true} />
<span>Number of unfinished todos:</span>
<TodoCounterForIsDoneValue isDone={false} />
</>
)
}