类组件中使用shouldComponentUpdate
shouldComponentUpdate用于控制组件是否需要重新渲染,通过这个方法,可以优化组件的性能,避免不必要的渲染
通过比较当前的props和state与下一个props和state,决定是否需要更新组件
例子中,只有当someValue发生变化时,组件才会重新渲染
class MyComponent extends React.Component {
shouldComponentUpdate(nextProps, nextState) {
// 比较当前和下一个 props/state
return nextProps.someValue !== this.props.someValue;
}
render() {
return <div>{this.props.someValue}</div>;
}
}
注意:shouldComponentUpdate是强业务逻辑相关的,如果使用这个API,必须考虑和此组件相关的所有props和state,如果有遗漏,就有可能出现数据和视图不统一的情况,所以使用时需要非常小心React.memo
React.memo是React v16.6中引入的新功能,是一个专门针对React函数组件的高阶组件
默认情况下,它和PureComponent一样,都是进行浅比较,是个高阶组件,在原有的组件上套一层就可以了
import React from 'react';
const MyComponent = ({ someValue }) => {
return <div>{someValue}</div>;
};
export default React.memo(MyComponent);
如果需要自定义比较逻辑,可以传入第二个参数
const MyComponent = ({ someValue }) => {
return <div>{someValue}</div>;
};
const areEqual = (prevProps, nextProps) => {
return prevProps.someValue === nextProps.someValue;
};
export default React.memo(MyComponent, areEqual);
PureComponent 是 React 中的一种类组件,类似于普通的 Component,但它自动实现了 shouldComponentUpdate 方法
特点:
import React, { PureComponent } from 'react';
class MyPureComponent extends PureComponent {
render() {
return <div>{this.props.someValue}</div>;
}
}
注意事项:
render() {
return (
<React.Fragment>
<ChildA />
< ChildB />
<ChildC />
< /React.Fragment>
);
}
render() {
return (
<>
<ChildA />
< ChildB />
<ChildC />
< />
);
}
React native开发做视图优化时,应该优先优化安卓,从下面几点做优化:
为什么要优先优化安卓?
例如,页面转场这个场景,可以把页面逻辑放在 InteractionManager.runAfterInteractions 的回调中执行,这样可以优先保证转场动画的执行,然后才是我们的页面逻辑,很好的规避了转场卡顿问题
**InteractionManager.runAfterInteractions:**这是一个 React Native 提供的工具,用于在所有交互(如动画)完成后执行某些任务。这样可以确保动画的流畅性
import React, { useEffect } from 'react';
import { View, Text, ActivityIndicator } from 'react-native';
import { InteractionManager } from 'react-native';
const MyComponent = () => {
const [loading, setLoading] = React.useState(true);
const [data, setData] = React.useState(null);
useEffect(() => {
// 假设这里是页面转场动画的开始
console.log('Page transition starts');
// 在转场动画完成后执行数据获取
const interactionPromise = InteractionManager.runAfterInteractions(() => {
// 模拟数据获取
fetchData().then(fetchedData => {
setData(fetchedData);
setLoading(false);
});
});
return () => {
// 清理
interactionPromise.cancel();
};
}, []);
const fetchData = async () => {
// 模拟一个数据获取过程
return new Promise(resolve => {
setTimeout(() => {
resolve('Fetched Data');
}, 2000);
});
};
return (
<View>
{loading ? (
<ActivityIndicator size="large" color="#0000ff" />
) : (
<Text>{data}</Text>
)}
</View>
);
};
export default MyComponent;
当我们呈现一个页面给用户时,一定是要在最短时间内让用户感觉到页面已经展示完毕,可以优先显示固定的占位信息,配合loading或骨架图布局不确定的部分,与此同时我们才在背后默默的发起请求(碰到复杂页面,则可拆分多个异步请求)