React Native - 将回调传递给另一个屏幕
React Native - pass callback to another screen
我有一个带表格的屏幕。现在在该表单中有一个按钮可以打开另一个屏幕,用户可以在其中选择目标选项,并且在选择后他们将导航回原始表单(堆栈导航器),原因是用户还可以在那里创建一个新选项以便他们转到UI 与单独编辑选项(他们可以)时一样。
我下面的代码解决方案有效,但是我收到以下警告:
Non-serializable values were found in the navigation state. This can
break usage such as persisting and restoring state. This might happen
if you passed non-serializable values such as function, class
instances etc. in params. If you need to use components with callbacks
in your options, you can use 'navigation.setOptions' instead. See
https://reactnavigation.org/docs/5.x/troubleshooting#i-get-the-warning-non-serializable-values-were-found-in-the-navigation-state
for more details.
现在 link 建议使用 setOptions
,但这更像是向 header 添加按钮,但事实并非如此,用户在目标屏幕中选择该选项通过点击选项。
以下是代码的重要部分:
// 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
是否有更好的方法将回调发送到另一个屏幕?
不建议通过route params
传递回调函数。从您的代码和您的解释来看,您实际上想要 pass data back to the screen on goBack
.
而不是做
route.params.onGoBack(item);
return navigation.goBack();
我们可以在 navigation.goBack()
上的路由参数中将 item
传回 MainFormScreen
,并在 useEffect
中直接在 MainFormScreen
中设置状态。这使我们不必在路由参数中传递函数。相反,我们直接在表单中设置状态。
OptionsScreen 我们可以像往常一样使用 navigate
并将 item
传回 MainFormScreen
而不是调用 goBack
return navigation.navigate('MainFormScreen', { item: item })
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])
我有一个带表格的屏幕。现在在该表单中有一个按钮可以打开另一个屏幕,用户可以在其中选择目标选项,并且在选择后他们将导航回原始表单(堆栈导航器),原因是用户还可以在那里创建一个新选项以便他们转到UI 与单独编辑选项(他们可以)时一样。
我下面的代码解决方案有效,但是我收到以下警告:
Non-serializable values were found in the navigation state. This can break usage such as persisting and restoring state. This might happen if you passed non-serializable values such as function, class instances etc. in params. If you need to use components with callbacks in your options, you can use 'navigation.setOptions' instead. See https://reactnavigation.org/docs/5.x/troubleshooting#i-get-the-warning-non-serializable-values-were-found-in-the-navigation-state for more details.
现在 link 建议使用 setOptions
,但这更像是向 header 添加按钮,但事实并非如此,用户在目标屏幕中选择该选项通过点击选项。
以下是代码的重要部分:
// 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
是否有更好的方法将回调发送到另一个屏幕?
不建议通过route params
传递回调函数。从您的代码和您的解释来看,您实际上想要 pass data back to the screen on goBack
.
而不是做
route.params.onGoBack(item);
return navigation.goBack();
我们可以在 navigation.goBack()
上的路由参数中将 item
传回 MainFormScreen
,并在 useEffect
中直接在 MainFormScreen
中设置状态。这使我们不必在路由参数中传递函数。相反,我们直接在表单中设置状态。
OptionsScreen 我们可以像往常一样使用 navigate
并将 item
传回 MainFormScreen
而不是调用 goBack
return navigation.navigate('MainFormScreen', { item: item })
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])