React 导航 didfocus 事件侦听器在类组件和功能组件之间的工作方式不同



当我过渡到这个屏幕时,它会做一些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();
}
}

控制台输出

从其他导航堆栈过渡到此屏幕:类版本

在同一堆栈中的屏幕之间转换:类版本

钩子版本

const someScreen = ({
navigation,
}) => {
useEffect(() => {
const navFocusListener = navigation.addListener('didFocus', () => {
// do some API calls here
API_CALL();
console.log('hooooks');
});
return () => {
navFocusListener.remove();
};
}, []);
}

控制台输出

从其他导航堆栈过渡到此屏幕:控制台中不显示任何内容

在同一堆栈中的屏幕之间过渡:呼呜呜

顺便说一句,这是我找到的解决方法

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();
};
}, []);
}

控制台输出

从其他导航堆栈过渡到此屏幕:重点部分

在同一堆栈中的屏幕之间过渡:侦听器部分

我想我找到了不一致行为的根本原因。 还有另一个钩子叫做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

相关内容

  • 没有找到相关文章

最新更新