问题
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