reactjs - 为什么 createStructuredSelector 不向组件发送道具?
问题描述
我一直在学习 Redux,我正在使用 Reselect 来记忆状态。我的大多数组件都与选择器一起工作得很好,但是有一个组件的createStructuredSelector
函数没有将部分数据发送到组件。
const mapStateToProps = createStructuredSelector({
currentUser: selectCurrentUser,
hidden: selectCartHidden
})
export default connect(mapStateToProps)(Header);
事实上,hidden
出于某种原因,只有属性会进入组件。currentUser
只是不在那里。
如果我在mapStateToProps
没有选择器的情况下重新使用,它会再次起作用。
const mapStateToProps = state => ({
currentUser: selectCurrentUser,
hidden: selectCartHidden
})
export default connect(mapStateToProps)(Header);
这是组件本身:
const Header = ({ currentUser, hidden }) => (
<div className="header">
<Link className="logo-container" to="/">
<Logo className="logo" />
</Link>
<div className="options">
<Link className="option" to="/shop">SHOP</Link>
<Link className="option" to="/contact">CONTACT</Link>
{
currentUser ?
<div className="option" onClick={() => auth.signOut()}>SIGN OUT</div>
:
<Link className="option" to="/signin">SIGN IN</Link>
}
<CartIcon />
</div>
{
hidden ? null : <CartDropdown />
}
</div>
)
如果问题只影响到这个组件,我不会太担心,因为我可以在没有选择器的情况下切换回原来的状态。但是由于某种原因,即使状态确实发生了变化,CartDropdown
子组件也不会在没有 的情况下重新渲染。createStructuredSelector
解决方案
我无法重现您的经历,一定是错字或其他原因:
const { Provider, connect } = ReactRedux;
const { createStore, applyMiddleware, compose } = Redux;
const { createStructuredSelector } = Reselect;
const initialState = {
currentUser: 'current user',
cartHidden: 'cart hidden',
};
const reducer = (state = initialState) => {
return state;
};
//selectors
const selectCurrentUser = (state) => state.currentUser;
const selectCartHidden = (state) => state.cartHidden;
//creating store with redux dev tools
const composeEnhancers =
window.__REDUX_DEVTOOLS_EXTENSION_COMPOSE__ || compose;
const store = createStore(
reducer,
initialState,
composeEnhancers(
applyMiddleware(() => (next) => (action) =>
next(action)
)
)
);
const mapStateToProps = createStructuredSelector({
currentUser: selectCurrentUser,
hidden: selectCartHidden,
});
const App = (props) => (
<pre>{JSON.stringify(props, undefined, 2)}</pre>
);
const ConnectedApp = connect(mapStateToProps)(App);
ReactDOM.render(
<Provider store={store}>
<ConnectedApp />
</Provider>,
document.getElementById('root')
);
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.8.4/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.8.4/umd/react-dom.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/redux/4.0.5/redux.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-redux/7.2.0/react-redux.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/reselect/4.0.0/reselect.min.js"></script>
<script src="https://unpkg.com/immer@7.0.5/dist/immer.umd.production.min.js"></script>
<div id="root"></div>
如果您无法获得更新的状态,那么我想您一定是在减速器中改变了状态
但是由于某种原因,如果没有 createStructuredSelector,CartDropdown 子组件将不会重新呈现,即使状态确实发生了变化。
你肯定在一个更糟糕的减速器中改变了状态;在组件或动作创建者中。
推荐阅读
- javascript - run multiple function call at once. but terminated all running function if one finished
- php - move_upload_file() 显示成功但文件未反映在目标文件夹中
- xpath - 使用 xpath 拆分时,Camel Splitter 实际上对 XML 文档做了什么?
- pine-script - 如何获得等于 TradingView Pine 脚本中当前值的最后一个值?
- json - 在scala中将CassandraRow转换为JSON表单字符串
- azure - 如何在访问外部资源的多个集群中部署的 Service Fabric 微服务中维护状态
- ocr - 在 Workfusion RPA Express 中使用 OCR 时“执行 OcrAction 时出错”。
- c# - 如何使用 TypeConverter 从 TimeSpan 转换为 DateTime 并返回?
- java - javax.media.NoDataSinkException
- python - 使用 pymysql.cursor() 将元组值插入 mysql 表