0

我想在原生应用小部件点击 android 后将用户导航到反应原生项目中的另一个屏幕。我能够在 MainView.js 中使用本机事件发射器捕获事件,并且我更改了其中一个组件的状态并且它发生了更改,但在此状态更改后 UI 未呈现。它显示空白屏幕,控制台上没有错误。提前感谢您的帮助!!

export default class MainView extends React.Component {
  constructor(props) {
    super(props);
    this.state = {text: 'Hi, This is main screen for app widget!!!'};
  }
  componentDidMount() {
    const eventEmitter = new NativeEventEmitter();
    this.listener = eventEmitter.addListener('MyCustomEvent', (event) => {
      console.log('MyCustomEvent -->', event);
      console.log('MyCustomEvent ArticleId -->', event.ArticleId);
      if (event.ArticleId === data.articleId) {
              console.log('data ArticleId true', data.articleId);
        //navigation.push('Article Details', data);
        this.setState({
              text: data.articleDes,
            });
             // setText(data.articleDes);
              console.log('text -->', this.state.text);

          } else {
        //  setText('No such article found.');
        console.log('text -->', this.state.text);
      }
    });
  }
  componentWillUnmount() {
    this.eventListener.remove(); //Removes the listener
  }
  render() {
    return (
      <View style={{flex: 1}}>
        <Text>{this.state.text}</Text>
        <Button
          title="click"
          onPress={() => this.props.navigation.push('Article Details', data)}
        />
      </View>
    );
  }
}

从 appwidget click 启动的 CustomActivity 源代码。从这个活动的 oncreate 中,我将事件发送到 react-native 主视图。

int articleId = 0;
    if (getIntent() != null) {
        articleId = getIntent().getIntExtra("articleId", 0);
        Log.e("articleid", "" + articleId);
    }
   //  Put data to map
    WritableMap payload = Arguments.createMap();
    payload.putInt("ArticleId", articleId);

    // Emitting event from java code
    ReactContext context = getReactNativeHost().getReactInstanceManager().getCurrentReactContext();
    if ( context != null && context.hasActiveCatalystInstance()) {
        Log.e("react context", "not null");
        (getReactNativeHost().getReactInstanceManager().getCurrentReactContext())
                .getJSModule(DeviceEventManagerModule.RCTDeviceEventEmitter.class)
                .emit("MyCustomEvent", payload);
    }
4

2 回答 2

0

那不是如何使用 NativeEventEmitter。您需要使用要从中发出事件的本机模块初始化 NativeEventEmitter:

import { NativeEventEmitter, NativeModules } from 'react-native';
const { myNativeModule } = NativeModules;

componentDidMount() {
    ...
    const eventEmitter = new NativeEventEmitter(myNativeModule);
    this.eventListener = eventEmitter.addListener('myEvent', (event) => {
       console.log(event.eventProperty) // "someValue"
    });
    ...
  }

  componentWillUnmount() {
    this.eventListener.remove(); //Removes the listener
  }

在此处阅读有关 NativeModules 的更多信息:https ://reactnative.dev/docs/native-modules-android

于 2020-10-28T09:17:25.260 回答
0

这听起来很熟悉我在 IOS 上遇到的问题。代码类似,但我不能保证 Android 中的底层结构以相同的方式工作。无论如何,我正在使用 NativeEventEmitter 从 IOS-Native(在 xCode 中以 swift 编写)发送事件消息到 React-native 文件。初始渲染后,值不会更新,据我了解,此问题不仅限于此类事件。经过一番谷歌搜索后,我发现您从该事件回调中的状态读取的所有内容都仅引用了第一个渲染,并且不会在未来的渲染中更新。

解决方案; 使用useRef以便保留对更新值的引用。useRef 在渲染和事件回调中保留值。这不是我自己发现的,请查看https://medium.com/geographit/accessing-react-state-in-event-listeners-with-usestate-and-useref-hooks-8cceee73c559React useState hook使用初始状态的事件处理程序,它们是值得称赞的。

于 2022-02-27T21:20:10.977 回答