react-navigation:是否可以将回调传递给 children (e.g.changeHandler)?

react-navigation: Is it possible to pass a callback to children (e.g.changeHandler)?

我一直在尝试的是将回调传递到屏幕

这是我的实验摘录...

export default class Test extends React.Component {
    constructor(props) {
        super(props);
    };

    handleOnPress(data){
    //How do we pass this callback to "Home" or "Sub"?
    }

    render() {
        const Navigator = StackNavigator({
            Home: {screen: Home},
            Sub:  {screen: Sub}
        });
        let data = {blah:"blah blah"};

        return (<Navigator screenProps={data} />);
    }
}

在这个例子中,我可以在HomeSub中得到this.props.screenProps.blah。 我以为能够传递 prop 也意味着能够传递回调,但我觉得我不对。

有人遇到过这个问题吗?

如有任何建议,我们将不胜感激。

如果您只想将回调传递给 child,您也可以在渲染中指定为道具:

<Navigator callback={this.handleOnPress} {/*And any other props you want to pass*/} />

然后在您的 HomeSub class 中触发您可能期望的回调

class Home extends React.Component {
    //...
    somefunction = () => {
        this.props.callback();
    }
}

这就是我现在在代码中使用的内容。

尽管如果您只想将其传递给 HomeSub 之一,这可能是您的答案:https://github.com/react-community/react-navigation/issues/935

const mapNavigationStateParamsToProps = (SomeComponent) => {
    return class extends Component {
        static navigationOptions = SomeComponent.navigationOptions; // better use hoist-non-react-statics
        render() {
            const {navigation: {state: {params}}} = this.props
            return <SomeComponent {...params} {...this.props} />
        }
    }
}

编辑:在我的例子中,我的处理程序是一个箭头函数,如下所示:

handleOnPress = (data) => {
    //Do something here
}

这样我就不用处理.bind()s

OP 的最终解决方案: 看起来 StackNavigator 需要将道具作为 screenProps 传递,因此渲染函数变为:

render() {
    const Navigator = StackNavigator({
        Home: {screen: Home},
        Sub:  {screen: Sub}
    });
    let props = {
        data: "data",
        handleOnPress: () => this.handleOnPress()
    };

    return (<Navigator screenProps={props} />);
}

不推荐通过 react native 导航参数传递回调,这可能会导致状态冻结(无法正确更新)。这里更好的解决方案是使用 EventEmitter,因此回调保留在 Screen1 中,并在 Screen2 发出事件时调用。

屏幕 1 代码:

import DeviceEventEmitter from "react-native"

DeviceEventEmitter.addListener("event.testEvent", (eventData) => 
callbackYouWantedToPass(eventData)));

屏幕 2 代码:

import DeviceEventEmitter from "react-native"

DeviceEventEmitter.emit("event.testEvent", {eventData});

useEffect(() => {
    return () => {
        DeviceEventEmitter.removeAllListeners("event.mapMarkerSelected")
    };
}, []);