嵌套Redux状态更新触发器在每个同级上呈现

问题描述 投票:0回答:1

描述:我正在尝试更新嵌套对象的状态。在更新嵌套对象时,我看到它的同级组件的render方法也被调用。

预期的行为:从我读过的所有文章中,它指定是否返回仅包含更新的嵌套对象的新对象,react足够聪明以仅呈现更新的对象。

示例:

reducer.tsx

// imports

const initialState = {
  firstLevel: {
    secondLevel: {
      jobLevel: {
        id: 'L52';
      },
      expectedSalary: {
        amount: '100000';
      }
    }
  }
}

export interface State {
  firstLevel: {
    secondLevel: {
      jobLevel: {
        id: string;
      },
      expectedSalary: {
        amount: string;
      }
    }
  }
}

export const mainState = (state: State = initialState, action) => {
  switch(action.type) {
    case 'NESTED_UPDATE':
      return {
        ...state,
        firstLevel : {
          secondLevel: {
            ...state.firstLevel.secondLevel,
            expectedSalary: {
              amount: '120000'
            }
          }
        }
      }
  }

}

因此,在上述redux状态下,我并不是在改变状态。我要返回在[firstLevel.secondLevel.expectedSalary]对象中发生更改的新对象。 firstLevel.secondLevel.jobLevel对象未更改时。

组件:

Main.tsx

// imports
class MainSection extends Component<> {
  // constructor and more logic

  render() {
    return (
      <div>
        <JobLevel {...props.firstLevel.secondLevel} />
      </div>
      <div>
        <ExpectedSalary 
          {...props.firstLevel.secondLevel}
          updateSecondLevel={this.props.updatedSecondLevel} //I know its included in props, for readability
        />
      </div>
  }
}

export default MainSection;

MainContainer.jsx

import {connect} from 'react-redux';
import {SplitActions, CreateRuleState} from '../types';
import RuleSplitSection from '../components/RuleSplitSection';
import Actions from '../actions/RuleDrawerActions';
import {calculateSplitRuleLineWidth} from '../utils/RuleUtil';

export const mapStateToProps = (state) => {
    return state;
};

export const mapDispatchToProps = dispatch => {
    return {
        updateSecondLevel: () => dispatch(Actions.updateSecondLevel())
    };
};

export default connect(
    mapStateToProps,
    mapDispatchToProps
)(Main as any);

子组件:JobLevel.jsx

class JobLevel extends Component<> {
  // constructor and more logic

  render() {
    return (
      // debug point 1
      <div>
        // assume TextField is another redux util component which takes some props as below.
        <TextField
          value={this.props.jobLevel}
          disabled // read only
        />
      </div>
  }
}

ExpectedSalary.jsx

class ExpectedSalary extends Component<> {
  // constructor and more logic

  updateExpectedSalarySecondLevel = evt => {
    const expectedSalaryObj = {amount: evt.target.value}
    this.props.updateSecondLevel('expectedSalary', expectedSalaryObj);
  } 


  render() {
    return (
      // debug point 2 
      <div>
        // assume TextField is another redux util component which takes some props as below.
        <TextField 
          onChange={this.updateExpectedSalarySecondLevel}
          value={this.props.expectedSalary}
        />
      </div>
  }
}

场景:在上述情况下,当我在ExpectedSalary Textfield中键入任何内容时,我现在将值硬编码为'120000'。我的理解是,当我更新ExpectedSalary subobject时,react非常聪明,只需要重新渲染ExpectedSalary子组件即可。但是从调试开始,我看到它在debug point 1 and 2处都停止。

我想知道为什么???现在,为了避免重新渲染JobLevel,我需要使用shouldComponentUpdate并检查如下所示的深层副本:

    shouldComponentUpdate(nextProps) {
        return this.props.jobLevel.id !== nextProps.jobLevel.id;
    }

所以我的问题是:1.进入JobLevel的render方法是反应生命周期的一部分吗?2.如果是这样,我需要避免吗?这是昂贵的过程吗?

如果需要更多代码参考,请告诉我是comments。我已经从简单的代码中排除了Actions文件,这是因为在这里键入很无聊。

描述:我正在尝试更新嵌套对象的状态。在更新嵌套对象时,我看到其同级组件的render方法也被调用。预期的行为:从所有...

javascript reactjs redux lifecycle
1个回答
0
投票

默认情况下,react在每次重新渲染时都会重新渲染所有组件。您需要将组件标记为Pure并具有稳定的道具,或者像执行操作那样实现componentDidUpdate以避免重新渲染。 react-reduxconnect个组件执行此操作。

© www.soinside.com 2019 - 2024. All rights reserved.