Nor*_*yan 3 reactjs redux react-redux reselect
我试图集成reselect到当前的应用程序中,并且一如既往,首先我开始阅读文档,然后如果需要的话,又重新整理了文档。我既不理解文档的一个特殊部分,也找不到能够在文档中解释的资源。更清晰的方式。现在我在这里得到一些明确的解释。所以它在文档中说
import React from 'react'
import Footer from './Footer'
import AddTodo from '../containers/AddTodo'
import VisibleTodoList from '../containers/VisibleTodoList'
const App = () => (
<div>
<VisibleTodoList listId="1" />
<VisibleTodoList listId="2" />
<VisibleTodoList listId="3" />
</div>
)
Run Code Online (Sandbox Code Playgroud)
将getVisibleTodos选择器与VisibleTodoList容器的多个实例一起使用将无法正确记住:
import { connect } from 'react-redux'
import { toggleTodo } from '../actions'
import TodoList from '../components/TodoList'
import { getVisibleTodos } from '../selectors'
const mapStateToProps = (state, props) => {
return {
// WARNING: THE FOLLOWING SELECTOR DOES NOT CORRECTLY MEMOIZE
todos: getVisibleTodos(state, props)
}
}
const mapDispatchToProps = (dispatch) => {
return {
onTodoClick: (id) => {
dispatch(toggleTodo(id))
}
}
}
const VisibleTodoList = connect(
mapStateToProps,
mapDispatchToProps
)(TodoList)
export default VisibleTodoList
Run Code Online (Sandbox Code Playgroud)
使用createSelector创建的选择器的缓存大小为1,并且仅在其参数集与之前的参数集相同时才返回缓存的值。如果我们在呈现
<VisibleTodoList listId="1" />和之间<VisibleTodoList listId="2" />切换,则共享选择器将在接收{listId: 1}和{listId: 2}作为其props参数之间切换。这将导致每次调用的参数都不同,因此选择器将始终重新计算而不是返回缓存的值。
注意最后一句话。如果我们传递不同的ids,为什么还要返回缓存的值,并且该值应该返回不同的值取决于ids呢?
因此,我们有一个选择器来获取VisibleTodoList组件的状态:
const mapStateToProps = (state, props) => {
return {
todos: getVisibleTodos(state, props)
}
}
Run Code Online (Sandbox Code Playgroud)
如果我们渲染组件:
return (
<div>
<VisibleTodoList listId="1" />
</div>
)
Run Code Online (Sandbox Code Playgroud)
然后,选择器将被调用为:getVisibleTodos(state, { listId: 1 }),然后选择器将结果(待办事项列表1对象)存储(记忆)在内存中。
如果我们使用相同的道具两次渲染组件:
return (
<div>
<VisibleTodoList listId="1" />
<VisibleTodoList listId="1" />
</div>
)
Run Code Online (Sandbox Code Playgroud)
选择器被调用并且结果被记忆
选择器第二次被调用,它发现它{ listId: 1 }与第一次具有相同的prop参数,因此它只返回备注值。
如果我们使用不同的道具两次渲染组件:
return (
<div>
<VisibleTodoList listId="1" />
<VisibleTodoList listId="2" />
</div>
)
Run Code Online (Sandbox Code Playgroud)
选择器被调用并且结果被记录
选择器第二次被调用,它发现{ listId: 2 }与第一次的道具args不同{ listId: 1 },因此它在内存中重新计算并存储新结果(待办事项列表2对象)(覆盖先前的存储记录)。
如果我们希望每个组件都有自己的备注,则每个组件实例必须具有自己的选择器实例。
例如:
// selector
const makeGetVisibleTodos = () => createSelector(
// ... get the visible todos
);
// each has their own memoization space:
const foo = makeGetVisibleTodos(); // this is an instance
const bar = makeGetVisibleTodos(); // this is a separate instance
Run Code Online (Sandbox Code Playgroud)
因此,将其应用于组件:
// component
const mapStateToProps = () => {
const getVisibleTodos = makeGetVisibleTodos(); // this instance get bound to the component instance
return (state, props) => {
return {
todos: getVisibleTodos(state, props)
}
}
}
Run Code Online (Sandbox Code Playgroud)
现在,如果我们使用不同的道具两次渲染组件:
return (
<div>
<VisibleTodoList listId="1" />
<VisibleTodoList listId="2" />
</div>
)
Run Code Online (Sandbox Code Playgroud)
与<VisibleTodoList listId="1" />选择的第一个实例被调用,结果被memoized
与<VisibleTodoList listId="2" />选择的不同实例被调用,结果被memoized