我有这个菜单组件,其中菜单上下文根据用户输入而改变。
例如,如果用户单击菜单中的RESERVATION按钮(图1),则网站主体将更改,菜单上下文也将更改以处理保留功能(图2)<---(期望的行为),但是,组件安装后,组件停止重新渲染。
图1: |主页|预订| ... |等
fig2: | <|预订| ... |等
我尝试过的事情:
看起来存储中的值也在更改并发送到组件。 我尝试使用componentWillReceiveProps(),但这没用。
这是我的菜单组件的示例:
import React, { Component } from 'react';
//redux thingy
import {connect} from 'react-redux';
class DefualtMenu extends Component {
render() {
return (
<div className="Defult-Menu-Main-Div">
<div className="box1">
<div className="box11" onClick={() => this.props.HandleMenuClick(this.props.MenuBoxes.box11)}>
<h3 className="boxh3" onClick={() => this.props.HandleMenuClick(this.props.MenuBoxes.box11)}>
{this.props.MenuBoxes.box11}
</h3>
</div>
</div>
</div>
);
}
}
const mapDispachToProps = (dispach) => {
return {
HandleMenuClick: (buttomName) => {
switch (buttomName){
case "RESERVATION":{
dispach({type: "HANDLE_BODY_CHANGE_RESERVATION"})
break;
}
}
}
}
}
const mapStateToProps = (state) => {
return {
MenuBoxes: state.MenuBoxes
}
}
export default connect(mapStateToProps, mapDispachToProps) (DefualtMenu);
这是我处理操作的方式:
const reducer = (state = initial_state, action) => {
const new_state = {...state};
switch (action.type) {
}
case "HANDLE_BODY_CHANGE_RESERVATION": {
new_state.body = 'reservation';
if(new_state.userType == 'customer'){
new_state.MenuBoxes.box11 = '◄'
new_state.MenuBoxes.box12 = 'DELETE A \n RESERVATION'
new_state.MenuBoxes.box13 = ''
new_state.MenuBoxes.box21 = 'MAKE A \n RESERVATION'
new_state.MenuBoxes.box22 = 'REVIEW \n RESERVATIONS'
new_state.MenuBoxes.box23 = ''
new_state.MenuBoxes.box31 = 'UPDATE A \n RESERVATION'
new_state.MenuBoxes.box32 = ''
new_state.MenuBoxes.box33 = ''}
break;
}
return new_state;
};
我console.log我的状态: 这是我登录到管理员帐户时的状态: 菜单组件确实已在此阶段安装,一切正常。
MenuBoxes:
box11: "HOME"
box12: "COUPONS"
box13: ""
box21: "RESERVATION"
box22: "ABOUT US"
box23: ""
box31: "INVENTORY"
box32: "SETTING"
box33: "SIGNOUT"
__proto__: Object
SingInfailureMessege: ""
body: "homepage"
isSignIn: true
showMenu: "default"
userType: "admin"
username: "admin"
当我单击“预订”时 ->菜单组件已经安装在这里,状态也改变了,但 组件没有重新渲染并更改道具
MenuBoxes:
box11: "◄"
box12: "DELETE A ↵ RESERVATION"
box13: ""
box21: "MAKE A ↵ RESERVATION"
box22: "REVIEW ↵ RESERVATIONS"
box23: ""
box31: "UPDATE A ↵ RESERVATION"
box32: ""
box33: ""
__proto__: Object
SingInfailureMessege: ""
body: "reservation"
isSignIn: true
showMenu: "default"
userType: "admin"
username: "admin"
答案 0 :(得分:1)
我不同意,您不需要这些:
componentWillReceiveProps(nextProps) // maybe not this one
componentDidUpdate(prevProps) // probably this one
shouldComponentUpdate(nextProps, nextState) // possibly this one but not likely
我的意思是这是react和redux的目的,状态更改->检查道具是否更改->如果是,则重新渲染。上面的功能对于比这更复杂的情况有用。
出问题的是减速器的编写方式。请尝试进行一些简单的测试。对于初学者,请尝试使用此开关:
switch (action.type) {
case "HANDLE_BODY_CHANGE_RESERVATION":
return { ...state, MenuBoxes: { box11: "test" } };
break;
default:
return state;
break;
}
我确定它会起作用。然后开始变得更复杂。
最后,我推测错误在于您在化简器中处理状态的方式。永远不要这样做:
const new_state = {...state};
这样做,您直接在下面进一步突变状态(我们从不这样做)。
您应该执行的方式是创建一个新对象,其中包括状态的所有更改:
let new_state = {};
...
new_state.body = "reservation";
new_state.MenuBoxes = {};
new_state.MenuBoxes.box12 = "DELETE A \n RESERVATION";
,最后返回以前的状态以及如下更改:
return { ...state, ...new_state };
我不是专家,但我认为,现在您要更改状态,所以新状态=旧状态=>无需重新渲染
答案 1 :(得分:1)
p
很好,这是MenuBoxes值的变异是一个问题
相反,您需要将嵌套对象和值从状态的顶部一直替换到需要更改的最终值。
const new_state = {...state};
在许多涉及深度嵌套的情况下,使用immer是一个不错的选择。 它将自动为您完成上述操作。
const reducer = (state = initial_state, action) => {
switch (action.type) {
case "HANDLE_BODY_CHANGE_RESERVATION": {
return { // replace state object with a new object
...state, // copy state values to new object as references
MenuBoxes: { // replace MenuBoxes object with a new object
...state.MenuBoxes, // copy Menuboxes values to new object as references
box11 = '◄', // update box values
box12 = 'DELETE A \n RESERVATION',
box13 = '',
box21 = 'MAKE A \n RESERVATION',
box22 = 'REVIEW \n RESERVATIONS',
box23 = '',
box31 = 'UPDATE A \n RESERVATION',
box32 = '',
box33 = ''
}
}
}
};
答案 2 :(得分:0)
您需要一些东西来检查道具的变化并手动更新组件。像
componentWillReceiveProps(nextProps) // maybe not this one
componentDidUpdate(prevProps) // probably this one
shouldComponentUpdate(nextProps, nextState) // possibly this one but not likely
我制作了一个codeandbox示例,该示例帮助某人通过Redux更改来更新其React组件。在这种情况下,我使用了componentDidUpdate()。