在所有流行的网站上,我都阅读了大量的文档,但是却找不到答案。 我在这里问我是否错过了一些文档,或者是至关重要的理解。
我看到的问题是,组件的mapStateToProps()函数仅被调用一次(在初始化时)。 即使调用了reducer,也再也不会调用它。 我开始认为这是因为我不了解如何将动作/还原器/道具捆绑在一起。
让我先说一句我知道的事情:
但是...我还没有找到有关动作,reduce和mapStateToProps如何相互关联的描述。 我的问题:
您是否浏览过http://redux.js.org/docs/Troubleshooting.html并验证您的案件不是它描述的问题之一?
我认为商店是一个对象,其属性包含有关应用程序状态的数据。 这些顶级属性可以是提供子树的对象,这些子树用于保存有关应用程序一部分的信息。 这是真的?
是的 Store在内部保存顶级状态对象。 它提供了从store.getState()
到该对象的访问。 该对象与您从根缩减器返回的内容相对应,并且通常类似于树。
将操作分派到商店时,将更新什么属性(或商店的子树)? 似乎在商店中会自动创建/关联属性,但是如何确定呢?
不,没有任何自动创建的东西。 商店只是开始指向调用根减速器的结果。
如果您的root reducer是您自己编写的函数,则其结果将是在分派操作后得到的结果:
function counter(state = 0, action) {
if (action.type === 'INCREMENT') {
return state + 1; // will become the next value of store.getState() after store.dispatch()
}
return state;
}
如果您使用combineReducers({ foo, bar })
类的根减速器来生成,则与您手动编写一个如下所示的根减速器相同:
function root(state = {}, action) {
return {
foo: foo(state.foo, action),
bar: bar(state.bar, action)
}
}
这是状态属性经常来自的地方。 它们的值分别取决于foo
和bar
减速器在处理操作时返回的值,因此,您又可以完全控制它们。
mapStateToProps如何“知道”侦听对商店的适当属性/部分的更新? 是什么将它们联系在一起?
您将mapStateToProps
传递给connect()
函数。 它生成一个组件,该组件使用store.subscribe()
来监听对商店的每次更改。 商店更改后,生成的组件将读取store.getState()
并将其传递给mapStateToProps()
以确定下一个要传递的道具。 如果它们更改了,它将与它们一起重新渲染您的组件。
我该如何调试? 我需要做些什么才能弄清楚为什么调度动作似乎没有触发mapStateToProps?
添加类似https://github.com/theaqua/redux-logger的中间件mapStateToProps
甚至都没有被呼叫,则意味着
dispatch()
一个动作,而是一个动作创建者,connect()
不必费心调用mapStateToProps()
。这两种情况都在http://redux.js.org/docs/Troubleshooting.html中进行了描述
将来,我们要求您首先尝试在StackOverflow上提问,并在确信库中存在可以通过示例共享的一致错误时,使用问题跟踪器。
谢谢!
依次回答:
{ users : {}, posts : {}, comments : {}, ui : {} }
。 请参阅http://redux.js.org/docs/FAQ.html#reducers -share-state和http://redux.js.org/docs/FAQ.html#organizing -state-nested-data。combineReducers
实用工具使拥有特定的reducer功能变得容易,该功能负责管理对给定数据片段的更新,例如: const combinedReducer = combineReducers({users : userReducer, posts : postReducer, comments : commentsReducer, ui : uiReducer});
connect()
函数,然后调用组件的mapStateToProps
以查看自上次以来提取的数据是否已更改。 没有特定的嵌套状态订阅。 请参阅http://redux.js.org/docs/FAQ.html#store -setup-subscriptions。希望这有助于清理问题。
除此之外,正如Dan所说:使用问题通常更适合Stack Overflow。 另外,Discord上的Reactiflux社区有很多专门针对React相关技术的聊天频道,包括Redux,并且总是有很多人愿意回答问题。 https://www.reactiflux.com上有一个邀请链接。
@ richb-hanover您可能已经见证了由react-redux连接执行的浅表比较。 这意味着嵌套在其他对象中的对象即使修改了它们也不会导致重新渲染,因为只检查了根键是否有修改。
http://redux.js.org/docs/faq/ReactRedux.html#why -isnt-my-component-re-rendering-or-my-mapstatetoprops-running
@ richb-hanover就我而言,@ gaearon检测到此问题:
或者您的化简返回了相同的参考值,因此connect()不必费心调用mapStateToProps()。
我正在使用此修复程序,这是结果代码
const mapStateToProps = (state, props) => {
return { id: props.id, currentState: state[props.id] };
}
const mapDispatchToProps = (dispatch) => {
return {
increment: (id) => {
dispatch({ type: 'INCREMENT', id: id })
}
}
}
const DumbListItem = ({
increment,
id,
currentState
}) => (
<div>
<li onClick={() => increment()}>{id}</li>
<span>{currentState}</span>
</div>
);
export const ConnectedListItem = connect(
mapStateToProps,
mapDispatchToProps
)(DumbListItem);
由于我没有将id
参数传递给增量调用(作为模板中的increment(id)
或通过mapDispatchToProps
的第二个参数),因此商店没有请正确更新,因此请检查是否可能是您的问题。
最有用的评论
您是否浏览过http://redux.js.org/docs/Troubleshooting.html并验证您的案件不是它描述的问题之一?
是的 Store在内部保存顶级状态对象。 它提供了从
store.getState()
到该对象的访问。 该对象与您从根缩减器返回的内容相对应,并且通常类似于树。不,没有任何自动创建的东西。 商店只是开始指向调用根减速器的结果。
如果您的root reducer是您自己编写的函数,则其结果将是在分派操作后得到的结果:
如果您使用
combineReducers({ foo, bar })
类的根减速器来生成,则与您手动编写一个如下所示的根减速器相同:这是状态属性经常来自的地方。 它们的值分别取决于
foo
和bar
减速器在处理操作时返回的值,因此,您又可以完全控制它们。您将
mapStateToProps
传递给connect()
函数。 它生成一个组件,该组件使用store.subscribe()
来监听对商店的每次更改。 商店更改后,生成的组件将读取store.getState()
并将其传递给mapStateToProps()
以确定下一个要传递的道具。 如果它们更改了,它将与它们一起重新渲染您的组件。添加类似https://github.com/theaqua/redux-logger的中间件
mapStateToProps
甚至都没有被呼叫,则意味着dispatch()
一个动作,而是一个动作创建者,connect()
不必费心调用mapStateToProps()
。这两种情况都在http://redux.js.org/docs/Troubleshooting.html中进行了描述
将来,我们要求您首先尝试在StackOverflow上提问,并在确信库中存在可以通过示例共享的一致错误时,使用问题跟踪器。
谢谢!