mapStateToProps 不更新具有切换状态的组件

Posted

技术标签:

【中文标题】mapStateToProps 不更新具有切换状态的组件【英文标题】:mapStateToProps not updating component with toggled state 【发布时间】:2020-05-06 14:15:19 【问题描述】:

Redux 的新用户,对于任何愚蠢的错误,我们深表歉意。最终,我试图切换组件 B 中的类名,因为 onClick 函数会切换组件 A 中的状态。

所以它应该是: 组件 A 按钮单击 => 状态切换 => 组件 B 类名切换。

我已经设置了我的商店,并且我的改变商店状态的 mapDispatchToProps 函数似乎正在工作。但是,在不同的组件中调用此状态是有效的……但是,不会随着商店中的状态切换而重新渲染。我的代码中有更多内容,但我试图去掉这个问题不需要的部分。

组件 A - 包含一个在我的 store/rootReducer 中切换状态和更改状态的按钮:

import React from 'react';
import  connect  from 'react-redux';


function Nav(props) 
  const [showMenu, setShowMenu] = React.useState('menuClosed');

  function menuClick() 
    showMenu === 'menuClosed' ? setShowMenu('menuOpen') :
      setShowMenu('menuClosed');
  

  // this works fine, I know this due to the console.log on my rootReducer page:
  React.useEffect(() => 
    props.toggleMenu(showMenu);
  , [showMenu])


  return (
    <button className="hvr-icon-grow-rotate" id="bars" onClick=() =>  menuClick(); >
      <FontAwesomeIcon icon=faBars className="hvr-icon" />
    </button>
  )


const mapStateToProps = (state) => 
  return 
    menu: state.menu
  


const mapDispatchToProps = (dispatch) => 
  return 
    toggleMenu: (showMenu) => 
      dispatch( type: 'TOGGLE_MENU', menu: showMenu )
    
  


export default connect(mapStateToProps, mapDispatchToProps)(Nav)

组件 B:应该根据商店状态切换类名:

import React from 'react';
import  connect  from 'react-redux';

const [noHover, setNoHover] = React.useState('projectGrid');

  React.useEffect(() => 
    console.log('portfolio props: ' + props.menu + ' noHover: ' + noHover);
    if (props.menu === 'menuOpen') 
      setNoHover('projectGrid noHover');
      console.log('portfolio props: ' + props.menu + ' noHover: ' + noHover);
    
    else if (props.menu === 'menuClosed') 
      setNoHover('projectGrid');
      console.log('portfolio props: ' + props.menu + ' noHover: ' + noHover);
    
  , [])

  return (<div className=noHover>some content</div>);


const mapStateToProps = (state) => 
  return 
    menu: state.menu
  


export default connect(mapStateToProps)(PortfolioItem)

最后,我的 rootReducer.js 页面或 Redux 商店的内容:

const initState = 
  menu: ['menuClosed']


const rootReducer = (state = initState, action) => 
  console.log(action);
  return state;


export default rootReducer;

任何帮助将不胜感激 - 谢谢!

【问题讨论】:

【参考方案1】:

看起来你实际上并没有在减速器中切换任何东西。

如果你想改变它,你需要返回一个新的状态。我不确定它在你的情况下应该是什么样子,但是是这样的:

const rootReducer = (state = initState, action) => 
  let newState = ...state; // Create a new state object so we don't mutate original
  switch(action.type)  // Check what type was sent to see if we should update
    case 'TOGGLE_MENU':
      newState.menu = action.menu; // Set new state based on action
      return newState;
    default:
      return state; // Return old state if nothing changed
  

旁注:看起来您的初始状态将菜单作为一个数组,但您的组件不会将其视为一个。似乎应该默认为字符串。

【讨论】:

【参考方案2】:

看起来@brian-thompson 已经解决了你的问题,所以我不会再解决它,但我想说你可以通过使用classnames 库使你的样式逻辑更容易成为日志。

你的 useEffect 回调将被替换为

const  menu  = props
const noHover = classNames(
  'projectGrid': true,
  'noHover': menu === 'menuOpen'
)

不再需要任何钩子。

【讨论】:

以上是关于mapStateToProps 不更新具有切换状态的组件的主要内容,如果未能解决你的问题,请参考以下文章

REACT + REDUX:在 redux 状态更改时 mapStateToProps 更新状态,但视图未按照新状态呈现

React Redux mapStateToProps 不会在更新时触发

React / Redux:mapStateToProps 实际上并未将状态映射到道具

商店状态更改时反应组件不更新

反应+还原。 Connect 不更新组件的状态

调度操作时未调用redux connect mapStateToProps