Open MacKenzieHnC opened 1 year ago
FYI there is some drift that I've seen in the instructions you were following: https://github.com/microsoft/react-native-windows-samples/issues/797
Long term there is desire for RN core to have a standard mechanism for creating a library from a template. It doesn't exist today, which is why there's so much variance in how each one is put together.
That said, you should be able to follow the docs we have and generate something successfully, so the next step here is to figure out what you're blocked on that's unclear and resolve that.
FYI there is some drift that I've seen in the instructions you were following: microsoft/react-native-windows-samples#797
Yes, I saw this, and meant to link to it to make that clear, my mistake. I dug deep into the issues section trying to find where my mistake was. The closest I could find was some error with Parse.sdk, but that seemed unlikely to be the problem, but I am still unclear if that sdk is part of RNW or not.
That said, you should be able to follow the docs we have and generate something successfully, so the next step here is to figure out what you're blocked on that's unclear and resolve that.
To the best of my knowledge and abilities, I have followed the instructions exactly, with the exception I already said about the custom metro config. I've never been able to get that to work.
But I have been able to get native views to work before. If this is truly user error, then the only place I see a gap in is that there aren't explicit instructions for how to install RNW into a pre-existing example app. I thought it was pretty self-explanatory, but perhaps that's where my mistake is? I also tried to cd
into the example folder and install RNW with whatever the init
function is called, but that led to the same errors, so that is not the method that the repo shows.
So is this almost certainly user error? This works for other people?
EDIT: I can confirm that the method is firing, at least.
Oh! I did use autolinking instead of manually linking the module, could that be the problem? I can test that out tonight.
Since I'm absolutely stuck on this, I've started trying to use a structure where the example folder has no package.json
or metro-config
, etc.
I made some progress after finding how to build a react-native.config, but I'm still running into errors.
Currently, I'm fighting an
error MIDL2011: [msg]unresolved type declaration [context]: Windows.UI.Xaml.Controls.Page [ RuntimeClass 'DocumentPickerExample.MainPage' ] [<example-directory>\windows\DocumentPickerExample\DocumentPickerExample.vcxproj]. Check your build configuration.
which, according to this, means I'm missing some kind of include
, but I suspect that's not really the issue since it's in a pre-built file. Is there some other weird change to the .vcxproj
file other than changing node-modules
location that needs to occur to make sure it knows where to find everything.
If I could figure out how to print out $(SolutionDir)
I could see if it's pointing to the right place, but I have no idea how to log from an xaml file.
Okay, still never figured that out, but it turns out my original issue that I didn't even post here was just a fundamental misunderstanding of what react-native-test-app
does and how to use it. I'm now unblocked on my current project, but still baffled about the problems I posted here.
I've returned to this and I'm still baffled. The following code is entered correctly, but the promise never gets returned to js. For some context, this is a module created with the default RN template.
tl;dr
// the module js function definition (index.tsx) (fully default)
export function multiply(a: number, b: number): Promise<number> {
return AwesomeModule.multiply(a, b);
}
// the windows module code (ReactNativeModule.h)
#pragma once
#include "NativeModules.h"
using namespace winrt::Microsoft::ReactNative;
namespace winrt::ReactNativeAwesomeModule
{
REACT_MODULE(ReactNativeModule, L"AwesomeModule") // Corrected from L"ReactNativeAwesomeModule"
struct ReactNativeModule
{
REACT_INIT(Initialize)
void Initialize(ReactContext const &reactContext) noexcept
{
m_reactContext = reactContext;
}
REACT_METHOD(Multiply, L"multiply")
void Multiply(double a, double b, ReactPromise<double> promise) noexcept
{
promise.Resolve(a * b); // Why doesn't this work???
}
private:
ReactContext m_reactContext{nullptr};
};
} // namespace winrt::ReactNativeDocumentPicker
This is mostly the same errors as before.
From the React Native Debugger:
Invariant Violation: Failed to call into JavaScript module method RCTDeviceEventEmitter.emit(). Module has not been registered as callable. Bridgeless Mode: false. Registered callable JavaScript modules (n = 0): .
A frequent cause of the error is that the application entry file path is incorrect. This can also happen when the JS bundle is corrupt or there is an early initialization error when loading React Native.
Invariant Violation: No callback found with cbID 0 and callID 0 for AwesomeModule.multiply - most likely the callback was already invoked. Args: '[21]'
Invariant Violation: Failed to call into JavaScript module method RCTDeviceEventEmitter.emit(). Module has not been registered as callable. Bridgeless Mode: false. Registered callable JavaScript modules (n = 0): .
A frequent cause of the error is that the application entry file path is incorrect. This can also happen when the JS bundle is corrupt or there is an early initialization error when loading React Native.
My current only guess is that the params for multiply
in RNW should be int, int, callback, promise
But I can't figure out the right type of callback.
This is somewhere where the docs seem to really fall flat. How does this idea of capturing the return values of the js functions work? (E.g. when the js outputs a promise and windows takes that promise as an input instead of outputting it)
Please help, I am willing to put in a tremendous amount of free labor updating compatible modules but I have to get over this first hump
@MacKenzieHnC Did you ever find the answer to this? I've got a REACT_METHOD
that never settles, too, whether I use the callback style or Promise style:
REACT_METHOD(randomBytes)
void randomBytes(uint32_t size, ReactPromise<const std::wstring> const& promise) noexcept {
promise.Resolve(this->GetRandomBytes(size));
}
The error surfaces as:
Invariant Violation: Failed to call into JavaScript module method JSTimers.callTimers(). Module has not been registered as callable. Bridgeless Mode: false. Registered callable JavaScript modules (n = 0): .
A frequent cause of the error is that the application entry file path is incorrect. This can also happen when the JS bundle is corrupt or there is an early initialization error when loading React Native.
I'm wondering if it happens when the Promise is wrapped in a Promise or something.
I found something which solved my case.
Instead of destructuring the APIs out of your native module, call them directly:
import { NativeModules } from "react-native";
- const { getConstants, randomBytes } = NativeModules.ReactNativeAppAuthJs;
- getConstants();
- randomBytes(16).then((result) => console.log(result));
+ NativeModules.ReactNativeAppAuthJs.getConstants();
+ NativeModules.ReactNativeAppAuthJs.randomBytes(16).then((result) => console.log(result));
I'm guessing that destructuring the APIs off of the module means that you end up taking a reference to each function without the this
context properly bound.
Perhaps you could do randomBytes.bind(NativeModules.ReactNativeAppAuthJs)(16)
to rebind the context, but that would make it so verbose again that you might as well just not destructure it in the first place.
I found another strange case.
Accessing any of these:
Platform.OS
Platform.constants.reactNativeVersion
Platform.Version
...would raise that same error:
Invariant Violation: Failed to call into JavaScript module method JSTimers.callTimers(). Module has not been registered as callable. Bridgeless Mode: false. Registered callable JavaScript modules (n = 0): .
A frequent cause of the error is that the application entry file path is incorrect. This can also happen when the JS bundle is corrupt or there is an early initialization error when loading React Native.
Invariant Violation: No callback found with cbID 1035 and callID 517 for module
. Args: '[3]'
In this case, avoiding destructuring didn't solve things. Really not sure what's going on, as I've been able to access Platform.OS
just fine from other modules in the graph. It doesn't seem to be a race condition (i.e. the Platform native module not being initialised yet), as it occurs even if we lazy-init it well into the lifespan of the app.
EDIT: I have been attempting to create a Turbo Module with backwards compatibility. These issues were also present with js module, but it's possible other options are unaffected. Also, Android does not have any of these issues.
Problem Description
Inconsistent issue, but about 50% of the time, initial build from this step fails with:
Running build again returns:
as though it was successful, so possibly ignorable?
Following the last 4 steps from this step leads to a situation where metro opens successfully and then does nothing. Not frozen, just awaiting some order I can't give it. Is there supposed to be a windows button in the console like there is for android and ios?
So the rest of these steps are done while skipping that portion.
Module template doesn't match RN template.
L"ReactNativeAwesomeModule"
should beL"AwesomeModule"
to match the call from the RN templatemultiply
.From there, following the Fancy math example leads to a host of errors. In order:
Function returns
undefined
.Solved by following this promise example
And something much harder to google for:
I vaguely understand that issue, but I don't see why it would appear. Searching through the files, references seem to be correct. (i.e. If you replace all the code in
App.tsx
with just showing a button or something, it behaves correctly). Possibly solved by this.Followed by a series of issues of the form:
Are these where that
callback
change to the .ts file are necessary?Some of these issues I've found half-hacks for, but ultimately, I have been unable to get it to function, and some clarity would be greatly appreciated.
Steps To Reproduce
1a. Either follow the native module setup guide using the RN template to create a C++/winRT library
1b. Or simply use my repro and run
yarn
from the main folderyarn example windows
Expected Results
Successful module template, ready to write in.
CLI version
10.2.0
Environment
Target Platform Version
10.0.19041
Target Device(s)
Desktop
Visual Studio Version
Visual Studio 2022
Build Configuration
Debug
Snack, code example, screenshot, or link to a repository
https://github.com/MacKenzieHnC/react-native-document-picker