React Native - 将回调传递到另一个屏幕

jav*_*web 2 javascript typescript react-native react-native-navigation

我有一个带有表格的屏幕。现在,在该表单中,有一个按钮可以打开另一个屏幕,用户可以在其中选择目标选项,选择后,他们将导航回原始表单(堆栈导航器),原因是用户还可以在那里创建一个新选项,以便他们转到与单独编辑选项时的用户界面相同(他们可以)。

我的解决方案下面的代码有效,我收到以下警告:

在导航状态中发现不可序列化的值。这可能会破坏持久化和恢复状态等使用。如果您在参数中传递不可序列化的值(例如函数、类实例等),则可能会发生这种情况。如果您需要在选项中使用带有回调的组件,则可以使用“navigation.setOptions”。 有关更多详细信息,请参阅 https://reactnavigation.org/docs/5.x/troubleshooting#i-get-the-warning-non-serialized-values-were-found-in-the-navigation-state 。

现在该链接建议使用setOptions,但这更像是在标题中添加按钮,但情况并非如此,用户通过单击选项在目标屏幕中选择该选项。

以下是代码的重要部分:

// MAIN FORM SCREEN
<Button title={"Some Title"} onPress={openSelectItem}></Button>

const openSelectFish = () => {
    return navigation.navigate("ItemList", { sendItemBack: true, onGoBack: onSelectItem });
};

const onSelectItem = (item: ItemDTO) => {
    setItem(item.name); // basic useState
};

// THE OPTIONS SCREEN
const onChooseItem = (item: ItemDTO) => {
    console.log(this);
    if ((typeof route !== "object") || (typeof route.params !== "object")) return;
    if (!route.params.sendItemBack ?? true) return;
    route.params.onGoBack(item);
    return navigation.goBack();
};
// onChooseItem is then used in onPress of each option
Run Code Online (Sandbox Code Playgroud)

有没有更好的方法如何将回调发送到另一个屏幕?

Dav*_*olz 5

不建议通过route params. 从您的代码和您的解释来看,您实际上想要pass data back to the screen on goBack

而不是做

route.params.onGoBack(item);
return navigation.goBack();
Run Code Online (Sandbox Code Playgroud)

我们可以直接传递itemMainFormScreen其路由参数 on并直接在 a 中navigation.goBack()设置状态。这使我们不必在路由参数中传递函数。相反,我们直接在表单中设置状态。MainFormScreenuseEffect

OptionsScreengoBack我们可以像navigate往常一样使用并传itemMainFormScreen

return navigation.navigate('MainFormScreen', { item: item })
Run Code Online (Sandbox Code Playgroud)

MainFormScreen在这里,我们不再传递函数,而是对路由参数更改做出反应。

const openSelectFish = () => {
    return navigation.navigate("ItemList", { sendItemBack: true });
};

const params = useMemo(() => route.params || {}, [route.params])

const [item, setItem] = useState()

const onSelectItem = useCallback((item: ItemDTO) => {
    setItem(item.name); // basic useState
}, [setItem]);

useEffect(() => {
   onSelectItem(params.item)
}, [params, onSelectItem])
Run Code Online (Sandbox Code Playgroud)

  • 这是因为 `navigation.navigate('RouteName') 会将新的路由推送到本机堆栈导航器(如果它尚未在堆栈中),否则它会跳转到该屏幕。`因为 `MainFormScreen` 已经在堆栈上并且我们已经导航从“Home”开始,它的后退按钮将导航回主页。通过使用从“OptionsScreen”导航,它会看到“MainFormScreen”已经在堆栈上,因此它“跳转”到它,而不是再次将其“推送”到堆栈上。(顺便说一句,这可以通过使用“push”来完成) (2认同)