reactNativeDriver - Why is Root not wrapped with createElement?
Javaherr opened this issue · 5 comments
reactNativeDriver() function in the current state is not mounting the app/running the application unless there is an initial emission on the stream to do the mounting of the app.
Is it because of missing createElement to be called on Root?
react-dom driver works fine because root was wrapped with createElement(Root) before mounting to container, while the react-native driver doesn't do it before registering component why?
Line 83 in 4d0f345
https://github.com/cyclejs/react-dom/blob/e1e5da8e998854344acdc117278e9c773ffecca3/src/index.ts#L10
André @staltz will it fix the react native app initial mounting problem? I don't know, I would like to learn.
Hi, if I understood your question correctly, this is simply how React Native works. Instead of calling "render", you just pass the App component (i.e. Root
) to registerComponent, and it's up to React Native to call createElement.
Hi André,
Thanks for looking into it and explaining this thing. I know you are very busy.
Let me explain what I am encountering.
import xs from 'xstream';
import {run} from '@cycle/run';
import {makeReactNativeDriver, TouchableOpacity, View, Text} from '@cycle/react-native';
// Just as explained in the repo example. Doesn't run the app
// function main(sources) {
// const inc = Symbol();
// const inc$ = sources.react.select(inc).events('press');
// const count$ = inc$.fold(count => count + 1, 0);
// const elem$ = count$.map(i =>
// TouchableOpacity(inc, [
// View([
// Text(`Counter: ${i}`),
// ])
// ]),
// ).debug('elem$');
// return {
// react: elem$,
// };
// }
function main(sources) {
const inc = Symbol();
const inc$ = sources.react.select(inc).events('press');
const count$ = inc$.fold(count => count + 1, 0);
// Case0 Just as explained in the repo example. Doesn't run the app
// Emission of react element happening before Running application / mounting application
const case0$ = count$.map(i =>
TouchableOpacity(inc, [
View({style: TestStyle},[
Text(`Counter: ${i}`),
])
]),
).debug('elem$');
// Case1 Immediate emission. Doesn't run the app
// Same as Case 0 Emission of react element happening before Running application / mounting application
const case1$ = xs.of(
TouchableOpacity(inc, [
View([
Text(`Counter`),
])
])
).debug('case1$')
// Case2 Periodic emission. Works.
// This case actually emits react element after running application/ mounting application and works
// What I noticed was that unless there is a periodic emission from the react stream the
// react native driver is not mounting the application.
const case2$ = xs.periodic(1).take(1).map(counter => {
return (
TouchableOpacity(inc, [
View({style: TestStyle},[
Text(`Counter: ${counter}`),
])
])
)
}).debug('case2$')
inc$.addListener({
next: e => console.log('pressed event')
})
return {
react: case2$,
};
}
run(main, {
react: makeReactNativeDriver('rncycle1'),
});
const TestStyle = {
display:'flex',
flexDirection:'column',
justifyContent:'center',
alignItems:'center',
backgroundColor: '#FFF176',
justifyContent: 'center',
height: 100
}
Hi André,
New to cycle, trying to create a react native app using it. The example you have on the readme.md does not work, it renders a blank screen. Also, I don't think it is events('click'), but events('press')... please advice!
Thanks
Having a similar problem, I think, but I'm also trying to use react-native-web https://gitlab.com/staltz/manyverse/-/merge_requests/139#note_478788767
I'm late to the party but in case its still relevant: also stumbled about this problem and could dig a little deeper (on android): because in the the ReactNative app talks through a callback with the java implementation during the setup phase it takes longer to initialize then the cyclejs code and hence the initial rendering is missed by it. @Javaherr's case2 example works because periodic has a timed delay build in.
I'm using it with somewhat ugly workaround, which makes all the examples work:
instead of:
import {run} from '@cycle/run';
[...]
run(main, {
react: makeReactNativeDriver('rncycle1'),
});
one cold use:
import {setup} from '@cycle/run';
import {AppRegistry} from "react-native";
// [...]
var cb;
const registerRootComponent = Root => {
return AppRegistry.registerComponent("myapp", () => {
cb();
return Root
});
}
cb = setup(main, {
react: makeReactNativeDriver("myapp", { registerRootComponent })
}).run
or
import {setup} from '@cycle/run';
// [...]
const program = setup(main, {
react: makeReactNativeDriver("myapp")
})
setTimeout(() => {program.run()}, 10);