为什么导航.goBack没有按我的预期工作?如何获取最后活动状态



我得到了3页

homepageproductListproductDetails

homepageproductList时,我通过一个路由参数

navigation.navigate('productList', { showCategory: 'productListA'} )

InitialProcess when component mounted

安装组件时,在productList页面内。我这样声明使用状态。

const {showCateory} = route.params;
const [activeTab, setActiveTab] = useState(showCateory);

并使用activeTab 调用api

useEffect(() => {
const unsubscribe = navigation.addListener('focus', () => {
async function fetchData() {
try {
await dispatch(
fetchProductList(
activeTab,
),
);
} catch (err) {
console.log(err);
} 
}
fetchData();
});
return unsubscribe;
}, []);

User Interaction

但我也在productList中添加了按钮,这样用户就可以更改当前活动选项卡

<TouchableOpacity onPress={() => changeTab()}></TouchableOpacity>
const changeTab = async () => {
await setActiveTab('productListB'),
await dispatch(fetchProductList(activeTab)
}

请注意,现在active tabdata coming from api is different是从组件开始安装时开始的。

Navigation Change again

当使用从productList转到productDetails时。一切都很好。

但在产品细节中,我将带着这个回到productList。navigation.goBack()

当我回到productList页面时,activeTab会变回productListA,数据会变回当component is mounted

调用navigation.goBack()时,我可以通过或更改路由参数吗?

在useEffect depedieces中添加activeTab

正如医生所说的

依赖项数组不会作为参数传递给effect函数。不过,从概念上讲,这就是它们所代表的:effect函数中引用的每个值也应该出现在dependencies数组中。将来,一个足够高级的编译器可以自动创建这个数组。

useEffect(() => {
const unsubscribe = navigation.addListener('focus', () => {
async function fetchData() {
try {
await dispatch(
fetchProductList(
//this value will always updated when activeTab change
activeTab,
),
);
} catch (err) {
console.log(err);
} 
}
fetchData();
});
return unsubscribe;
}, [activeTab]); //<<<<< here

您还需要知道setState((并不总是立即更新组件。请参阅此处
因此更改此

const changeTab = async () => {
//await setActiveTab('productListB'),
//await dispatch(fetchProductList(activeTab)
setActiveTab('productListB')
dispatch(fetchProductList('productListB'))
}

这可能是因为当您返回屏幕时,route.params仍设置为{ showCategory: 'productListA'}

如果是这种情况,您可以通过像一样更改changeTab()中的params对象来修复它

navigation.setParams({
showCategory: 'productListB',
});

我希望这能解决你的问题。

之所以会发生这种情况,是因为焦点侦听器内部的回调函数在定义函数时(在初始页面呈现时(使用状态的初始值。在侦听器的整个生命周期中,回调函数都使用这个过时的状态值。你可以在这个答案中阅读更多关于这种行为的信息

尽管Ahmed Gaber的答案在这种情况下有效,因为侦听器在每次状态更改后都会被清除和重新定义。另一个常见的解决方法是使用useRef而不是useEffect。ref基本上是一个配方,它提供了一个可以通过引用传递的可变对象。

在您的情况下,您可以使用useRef钩子将导航参数值的activeTab初始化为:

const activeTab = useRef(showCateory);

并且焦点侦听器回调函数应该更改为使用引用当前值作为

useEffect(() => {
const unsubscribe = navigation.addListener('focus', () => {
async function fetchData() {
try {
await dispatch(
fetchProductList(
activeTab.current, //<<<<<<---------here
),
);
} catch (err) {
console.log(err);
} 
}
fetchData();
});
return unsubscribe;
}, []);

changeTab功能可以直接更新参考电流值

const changeTab = async () => {
setActiveTab.current = 'productListB';
dispatch(fetchProductList('productListB'))
}

最新更新