[英]mapStateToProps not updating component with toggled state
new user to Redux so apologies for any silly mistakes. Redux 的新用户,对于任何愚蠢的错误深表歉意。 Ultimately, I am trying to toggle a className in component B as an onClick function toggles a state in component A.
最终,我试图在组件 B 中切换一个类名,因为 onClick 函数在组件 A 中切换一个状态。
So it should be: Component A button click => state toggles => Component B className toggles.所以它应该是:组件 A 按钮单击 => 状态切换 => 组件 B className 切换。
I have setup my store and my mapDispatchToProps function that changes the state in my store seems to be working.我已经设置了我的商店,我的 mapDispatchToProps 函数改变了我商店的状态似乎正在工作。 However, calling this state in a different component is working... but, does not re-render as the state in the store toggles.
但是,在不同的组件中调用此状态是有效的......但是,不会随着商店中的状态切换而重新呈现。 There is more content in my code, but I've tried to strip the parts that are not necessary to this issue.
我的代码中有更多的内容,但我已经尝试删除了这个问题不需要的部分。
Component A - containing a button that toggles a state and changes a state within my store/rootReducer:组件 A - 包含一个按钮,用于切换状态并更改我的商店/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)
Component B: supposed to toggle a className depending on store state:组件 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)
finally, content of my rootReducer.js page, or the Redux store:最后,我的 rootReducer.js 页面或 Redux 商店的内容:
const initState = {
menu: ['menuClosed']
}
const rootReducer = (state = initState, action) => {
console.log(action);
return state;
}
export default rootReducer;
Any help would be greatly appreciated - thank you!任何帮助将不胜感激 - 谢谢!
It doesn't look like you're actually toggling anything in your reducer.看起来您实际上并没有在减速器中切换任何东西。
You need to return a new state if you want it to change.如果你想让它改变,你需要返回一个新的状态。 I'm not sure exactly how it should look in your case, but something like this:
我不确定在你的情况下它应该是什么样子,但是是这样的:
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
}
}
Side note: it looks like your initial state has menu as an array, but your components don't treat it as one.旁注:看起来您的初始状态将菜单作为数组,但您的组件不会将其视为一个数组。 It seems like it should be defaulted to a string.
它似乎应该默认为一个字符串。
It looks like @brian-thompson has solved your problem, so I won't solve it again, but I would say you can make your styling logic a log easier by using the classnames library.看起来 @brian-thompson 已经解决了你的问题,所以我不会再解决它,但我会说你可以通过使用类名库使你的样式逻辑更容易成为日志。
Your useEffect callback would be replaced with您的 useEffect 回调将替换为
const { menu } = props
const noHover = classNames({
'projectGrid': true,
'noHover': menu === 'menuOpen'
})
Removing the need for any hooks.无需任何挂钩。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.