首页 > 解决方案 > 为什么 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

标签: reactjsreduxreselect

解决方案


我无法重现您的经历,一定是错字或其他原因:

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 子组件将不会重新呈现,即使状态确实发生了变化。

你肯定在一个更糟糕的减速器中改变了状态;在组件或动作创建者中。


推荐阅读