更新Redux存储后,我的组件不会重新呈现

时间:2019-03-14 21:26:03

标签: javascript reactjs redux

我有这个菜单组件,其中菜单上下文根据用户输入而改变。

例如,如果用户单击菜单中的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;
};

UPDATE

我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"

3 个答案:

答案 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()。

https://codesandbox.io/s/88xyxjm30l