代码之家  ›  专栏  ›  技术社区  ›  jave.web

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

  •  0
  • jave.web  · 技术社区  · 4 年前

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

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

    在导航状态中找到了不可序列化的值。这个可以 中断使用,例如持久化和恢复状态。这可能会发生 如果传递了不可序列化的值,如函数、类 params中的实例等。如果需要使用带有回调的组件 在选项中,可以使用“navigation.setOptions”。看见 https://reactnavigation.org/docs/5.x/troubleshooting#i-get-the-warning-non-serializable-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
    

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

    0 回复  |  直到 4 年前
        1
  •  2
  •   David Scholz    4 年前

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

    而不是做

    route.params.onGoBack(item);
    return navigation.goBack();
    

    我们可以通过 item 返回到 MainFormScreen 在其路线参数上 navigation.goBack() 并直接在中设置状态 主窗体屏幕 在 useEffect 。这使我们不必在路由参数中传递函数。相反,我们直接在表单中设置状态。

    选项屏幕 而不是打电话 goBack ,我们可以使用 navigate 照常通过 项目 回到 主窗体屏幕

    return navigation.navigate('MainFormScreen', { item: item })
    

    主窗体屏幕 在这里,我们不再传递函数,而是对路由参数的更改做出反应。

    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])
    
    推荐文章