chi*_*ote 7 javascript reactjs react-native react-navigation react-hooks
当我切换到此屏幕时,它将执行一些API调用以获取最新数据。但是,当我从另一个带有钩子版本的导航堆栈过渡时,它似乎并不会触发didFocus事件触发api调用,而它与类版本很好地兼容。
如何使钩子版本具有与类版本相同的行为?
这两个版本有什么区别?
class someScreen extends Component {
componentDidMount() {
const {
navigation,
} = this.props;
this.navFocusListener = navigation.addListener('didFocus', () => {
// do some API calls here
console.log("class version");
API_CALL();
});
}
componentWillUnmount() {
this.navFocusListener.remove();
}
}
Run Code Online (Sandbox Code Playgroud)
从其他导航堆栈到此屏幕的转换:类版本
同一堆栈中屏幕之间的转换:类版本
const someScreen = ({
navigation,
}) => {
useEffect(() => {
const navFocusListener = navigation.addListener('didFocus', () => {
// do some API calls here
API_CALL();
console.log('hooooks');
});
return () => {
navFocusListener.remove();
};
}, []);
}
Run Code Online (Sandbox Code Playgroud)
从其他导航堆栈过渡到此屏幕:控制台中未显示任何内容
同一堆栈中的屏幕之间的过渡:挂钩
顺便说一句,这是我找到的解决方法
const someScreen = ({
navigation,
}) => {
useEffect(() => {
const isFocused = navigation.isFocused();
// manually judge if the screen is focused
// if did, fire api call
if (isFocused) {
// do the same API calls here
API_CALL();
console.log('focused section');
}
const navFocusListener = navigation.addListener('didFocus', () => {
// do some API calls here
API_CALL();
console.log('listener section');
});
return () => {
navFocusListener.remove();
};
}, []);
}
Run Code Online (Sandbox Code Playgroud)
控制台输出
从其他导航堆栈过渡到此屏幕:重点部分
同一堆栈中屏幕之间的转换:侦听器部分
我想我找到了不一致行为的根本原因。还有另一个名为 useLayoutEffect 的钩子
useLayoutEffect 签名与 useEffect 相同,但它在所有 DOM 更改后同步触发。使用它从 DOM 读取布局并同步重新渲染。在浏览器有机会绘制之前,useLayoutEffect 内计划的更新将同步刷新。
useLayoutEffect 会阻止绘画,而 useEffect 不会。这证实并解释了我的猜测,即 didFocus 事件已触发,但它没有触发侦听器,因为它错过了时机
所以就我而言,我必须使用 useLayoutEffect 而不是 useEffect
参考:https: //kentcdodds.com/blog/useeffect-vs-uselayouteffect https://reactjs.org/docs/hooks-reference.html#uselayouteffect
| 归档时间: |
|
| 查看次数: |
289 次 |
| 最近记录: |