Pure Component works like normal component when i pass object as a prop?

允我心安 提交于 2020-06-17 09:50:10

问题


I have a pure Component like this?

interface CheckBoxOptions {
  multiSelected?: boolean
  showOuterCheckBoxOnSelected?: boolean
}

interface Props {
  checkBoxKey?: any
  itemTitle?: string
  isCheckBoxSelected?: boolean
  checkBoxStyle?: any
  mainContainerStyle?: any
  checkBoxTitleStyle?: any
  checkBoxBackgroundColor?: any
  onPressCheckBox?: (id, isChecked, selectedArray , options?: CheckBoxOptions) => void
  itemKey?: any
  options?: CheckBoxOptions
}

In this i need this options interface since the no can increase

Now when i use this pureComponents in my otherComponent

renderCheckBoxComponent = (checkBoxKey , checkBoxList ) => {
    const totalCheckBoxelements = checkBoxList && checkBoxList.length
    log('renderCheckBoxComponent', checkBoxList )
    const {onPressChackBox} = this.props
   return  checkBoxList && checkBoxList.map((item , index) => {
        return (
        <View style={[ styles.checkBoxContainer , { borderBottomWidth: (index === totalCheckBoxelements - 1) ? 1 : 0 }]}>
            <CheckBoxComponent
                    checkBoxKey={checkBoxKey}
                    itemKey={get(item , 'id')}
                    itemTitle={get(item , 'name', '')}
                    isCheckBoxSelected={get(item , 'isChecked' , '')}
                    onPressCheckBox={onPressChackBox}
                    checkBoxBackgroundColor={colors.DuckBlue}
                    options = {get(item, 'options')}


                />
        </View>
               )
        })
}

If i don't pass the prop options then it works fine, it renders only when there is some change.

But if i pass options prop in props then it renders everytime even if no change. Each render makes the performance slower . Is there is any way to fix it or why it is occuring so.


回答1:


By default Pure Component will only shallowly compare complex objects in the props, they do not compare the content of the object you are passing, you have to override the shouldComponentUpdate lifecycle somehow, in order to stop re-render.

In your case, options = {get(item, 'options')} it seems like you are passing the new object on every parent re-render, if you start passing the same object then also it will create a problem because PureComponent will never find the difference in object keys

for ClassBased Component:

class MyComponent extends React.Component {
  shouldComponentUpdate(nextProps) {
    if (
      nextProps.options !== this.props.options &&
      nextProps.options.multiSelected !== this.props.multiSelected &&
      nextProps.options.showOuterCheckBoxOnSelected !==
        this.props.showOuterCheckBoxOnSelected
    ) {
      return false;
    }
    return true;
  }

  render() {
    return <div>{"My Component " + this.props.value}</div>;
  }
}

For Functioional component you need to use the React.memo like this

const MyNewComponent = React.memo(
  (props) => {
    <MyComponent {...props} />;
  },
  (oldProps, newProps) => {
    if (
      oldProps.options !== newProps.options &&
      oldProps.options.multiSelected !== newProps.multiSelected &&
      oldProps.options.showOuterCheckBoxOnSelected !==
        newProps.showOuterCheckBoxOnSelected
    ) {
      return true;
    }
    return false;
  }
);


来源:https://stackoverflow.com/questions/62218097/pure-component-works-like-normal-component-when-i-pass-object-as-a-prop

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!