我有如下情況
我有一個標簽導航器,每個標簽都有堆疊導航器。例如,

const AppContainer = createStackNavigator();
<AppContainer.Navigator
initialRouteName="BottomTabScreens"
screenOptions={{
gestureEnabled: true,
headerShown: false,
...TransitionPresets.SlideFromRightIOS,
}}
>
<AppContainer.Screen
name="BottomTabScreens"
component={BottomTabScreens}
/>
{...some other routes}
</AppContainer.Navigator>
然后在BottomTabScreens.tsx我里面,
<Tab.Navigator
initialRouteName="A"
screenOptions={({ route }) => ({
tabBarIcon: ({ focused }) => {
const { name } = route;
return (
<Image source={TabIcons(focused, name)} style={TabStyles.tabIcon} />
);
},
// some style props
})}
>
<Tab.Screen
name="A"
component={B}
options={{ headerShown: false }}
/>
<Tab.Screen
name="B"
component={BStack} <-----------------------------------Notice here
options={{ headerShown: false }
/>
<Tab.Screen
name="C"
component={CStack}
/>
</Tab.Navigator>
現在里面BStack.tsx我有,
<Stack.Navigator initialRouteName="B1">
<Stack.Screen
name="B1"
component={BSubScreen1} <------------ This is the middle UI of the above prototype
options={{ headerShown: false }}
/>
<Stack.Screen
name="B2"
component={BSubScreen2} <------------ This is the last UI of the above prototype
options={headerOptions}
/>
</Stack.Navigator>
然后我嘗試從堆疊 C 導航到堆疊 B ( BScreen2 ) 的嵌套螢屏。
navigation.navigate("B2")
當我從堆疊 c 的嵌套螢屏執行此操作時,出現以下錯誤,
任何導航器都沒有處理負載為 {"name":"B2","params":{"slug":"slug-id-1"}} 的操作“NAVIGATE”。
你有一個名為“B2”的螢屏嗎?
如果您嘗試導航到嵌套導航器中的螢屏,請參閱 https://reactnavigation.org/docs/nesting-navigators#navigating-to-a-screen-in-a-nested-navigator。
所以我改變了導航命令如下,
navigation.navigate("B", {
screen: "B1",
params: {
slug: 'slug-id-1'
}
})
這有效,但問題是,如果我導航回堆疊 C 并嘗試使用不同的引數轉到 B1,它不會重新呈現 B1 螢屏的 UI。但是在控制臺中,我可以清楚地看到 API 獲取了新 slug 的新資料。
同樣使用上面的導航命令,B1螢屏也沒有顯示后退按鈕
我在這里做錯了什么?
注意 - 我替換了組件名稱 ( B1, B2 ) 以簡化描述
B2畫面內容
export const B2: React.FC<BasicNavigation> = ({ navigation, route }) => {
const [loading, setLoading] = useState(false);
const [name, setName] = useState("");
const [data, setData] = useState([]);
const fetchData = async () => {
try {
const {
params: { slug }
} = route;
const { name } = await getPeopleMeta(slug);
const { data } = await getPeopleBooks(slug);
setName(name.toUpperCase());
const filterredBooks = data.map(({ image, slug, title }) => {
return { uri: posterSelector(image), slug, title };
});
setData(filterredBooks);
setLoading(false);
} catch (error) {
// TODO: Display Error page
setLoading(false);
}
};
const onPress = () => {
throw new Error("Not Implemented");
};
const onAlltrialerBtnPress = () => {
navigation.goBack();
};
useEffect(() => {
setLoading(true);
fetchData();
}, []);
if (loading) {
return <Spinner />;
}
return (
<ScrollView style={{ backgroundColor: "white" }}>
<NameSection title={name} />
<GridComponent items={data} onPress={onPress} />
<GreyButton
text="SEE ALL NEW"
disable={false}
onPress={onAlltrialerBtnPress}
/>
</ScrollView>
);
};
uj5u.com熱心網友回復:
如果您可以看到當您回到 B1 時您正在從 API 獲取資料,則意味著您可能正在渲染一個平面串列,當新資料到來時,該串列不會重新渲染。您可以使用道具extraData重新渲染平面串列。
B1 螢屏默認不會顯示后退按鈕,因為它是 B 堆疊的起始螢屏。
uj5u.com熱心網友回復:
B2 UI沒有更新的原因是從C堆疊回傳的時候。該組件將不會再次安裝。沒有 deps 的 useEffect 不會再次呼叫。因此,有兩種方法可以解決您的問題。
- 在 useEffect 中添加 dep
const fetchData = async (slug) => {
try {
const { name } = await getPeopleMeta(slug);
const { data } = await getPeopleBooks(slug);
setName(name.toUpperCase());
const filterredBooks = data.map(({ image, slug, title }) => {
return { uri: posterSelector(image), slug, title };
});
setData(filterredBooks);
setLoading(false);
} catch (error) {
// TODO: Display Error page
setLoading(false);
}
};
useEffect(() => {
setLoading(true);
fetchData(route.params?.slug);
}, [route.params?.slug]);
- 使用useFocusEffect 鉤子
轉載請註明出處,本文鏈接:https://www.uj5u.com/yidong/404430.html
標籤:
