Skip to content

Commit

Permalink
Cxx TurboModules > Add example to return a JS function from Cxx to JS (
Browse files Browse the repository at this point in the history
…#41385)

Summary:
Pull Request resolved: #41385

Changelog: Internal

Adding a Cxx TM example which adds a listener and returns a subscription to remove that listener from the TM.

You should be able to use this with React Hooks - https://legacy.reactjs.org/docs/hooks-reference.html

E.g.

```
useEffect(() => {
  const subscription =  NativeCxxModuleExample.setValueCallbackWithSubscription(
          callbackValue => // use it
        );
  return subscription;
});
```

Reviewed By: shwanton

Differential Revision: D50473063

fbshipit-source-id: 4e9b92aeccff1771eb4ffad6bdaa20ba7f18435f
  • Loading branch information
christophpurrer authored and facebook-github-bot committed Nov 9, 2023
1 parent 01b4d78 commit 9320174
Show file tree
Hide file tree
Showing 4 changed files with 33 additions and 0 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,18 @@ void NativeCxxModuleExample::getValueWithCallback(
callback({"value from callback!"});
}

std::function<void()> NativeCxxModuleExample::setValueCallbackWithSubscription(
jsi::Runtime& rt,
AsyncCallback<std::string> callback) {
valueCallback_ = std::make_optional(callback);
return [&]() {
if (valueCallback_.has_value()) {
valueCallback_.value()({"value from callback on clean up!"});
valueCallback_ = std::nullopt;
}
};
}

std::vector<std::optional<ObjectStruct>> NativeCxxModuleExample::getArray(
jsi::Runtime& rt,
std::vector<std::optional<ObjectStruct>> arg) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
#include <AppSpecs/AppSpecsJSI.h>
#endif
#include <memory>
#include <optional>
#include <set>
#include <string>
#include <vector>
Expand Down Expand Up @@ -107,6 +108,10 @@ class NativeCxxModuleExample
jsi::Runtime& rt,
AsyncCallback<std::string> callback);

std::function<void()> setValueCallbackWithSubscription(
jsi::Runtime& rt,
AsyncCallback<std::string> callback);

std::vector<std::optional<ObjectStruct>> getArray(
jsi::Runtime& rt,
std::vector<std::optional<ObjectStruct>> arg);
Expand Down Expand Up @@ -169,6 +174,9 @@ class NativeCxxModuleExample
ObjectStruct getObjectAssert(jsi::Runtime& rt, ObjectStruct arg);

AsyncPromise<jsi::Value> promiseAssert(jsi::Runtime& rt);

private:
std::optional<AsyncCallback<std::string>> valueCallback_;
};

} // namespace facebook::react
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,9 @@ export interface Spec extends TurboModule {
+getUnion: (x: UnionFloat, y: UnionString, z: UnionObject) => string;
+getValue: (x: number, y: string, z: ObjectStruct) => ValueStruct;
+getValueWithCallback: (callback: (value: string) => void) => void;
+setValueCallbackWithSubscription: (
callback: (value: string) => void,
) => () => void;
+getValueWithPromise: (error: boolean) => Promise<string>;
+getWithWithOptionalArgs: (optionalArg?: boolean) => ?boolean;
+voidFunc: () => void;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,16 @@ class NativeCxxModuleExampleExample extends React.Component<{||}, State> {
NativeCxxModuleExample?.getValueWithCallback(callbackValue =>
this._setResult('callback', callbackValue),
),
callbackWithSubscription: () => {
const subscription =
NativeCxxModuleExample?.setValueCallbackWithSubscription(
callbackValue =>
this._setResult('callbackWithSubscription', callbackValue),
);
if (subscription) {
subscription();
}
},
getArray: () =>
NativeCxxModuleExample?.getArray([
{a: 1, b: 'foo'},
Expand Down

0 comments on commit 9320174

Please sign in to comment.