shirakaba / react-nativescript

React renderer for NativeScript
https://react-nativescript.netlify.com
MIT License
280 stars 14 forks source link

Problem using SegmentedBar #35

Closed Lelelo1 closed 5 years ago

Lelelo1 commented 5 years ago

I get the following error using $SegmentedBar in my tsx:

UsingSegmentedBar

file:///node_modules/tslib/tslib.es6.js:121:0 JS ERROR TypeError: undefined is not an object (evaluating 'o[Symbol.iterator]')

shirakaba commented 5 years ago

Not a known error... I'll need more information here.

Check that you're navigating to the page correctly

How are you navigating to this page? I'd usually expect this.pageRef to be passed in as a prop (e.g. this.props.forwardedRef), unless you've got a $Frame wrapping that $Page.

Check your $Page's children

I don't know what AppBar and MainScreen correspond to, but I should clarify that a $Page can only take one content child (it's a single-view component).

There are certain technicalities to this:

You can nest extra $Pages inside any $Page (I make a special exception to allow this pattern, as it makes navigation much easier to set up; $Pages always establish a new, detached, component tree). In other words, $Page does not act as a content child.

ActionBar also does not act as a content child (it updates the actionBar property rather than the content property).

So if MainScreen is a content child, for example, it would have taken the place of $SegmentedBar, and you'd have to wrap both in a $StackLayout in order for both to display (unless MainScreen doesn't act as a content child, as explained above).

I may have implemented $SegmentedBar incorrectly

I'm not totally sure what a SegmentedBar is. I made a brief test with it, then moved on. I may need to revisit it.

Minimal reproduction

Could you reproduce this as a minimum working example (something that I can run)? Without knowing the code around that code snippet, it's a bit hard for me to reproduce.

Lelelo1 commented 5 years ago

I created a repro sample following the steps to create a new project.

The image does not correspond to how I initially used it (wrapped in layout indeed). I was in a hurry so I copied it into the project of the image - but it does produce the same error.

I also checked in vanilla ts Nativescript project. There is no error from simply adding the component (into a layout).

shirakaba commented 5 years ago

Perfect, that helps a lot!

I can see a problem here. $Page is a single-view component. I believe the React HostConfig will first encounter the $Label child and add that as the content view, then it will find the next child ($SegmentedBar) and will set that as the $Page's content view instead. So actually, I'd expect it to discard the $Label and for the $SegmentedBar to become visible. So there may indeed be a library bug in here.

For both to be visible at the same time, They'd need to be nested together in a $StackLayout.

Does the error stop if you:

  1. Comment-out the $Label component?
  2. And otherwise, if you nest the $Label and $SegmentedBar together in a $StackLayout?

I'll be able to play with the code in a few hours, but for now, if you could answer both of those questions, we'd be able to determine whether it's a library bug or simply incorrect usage of $SegmentedBar.

Thanks for comparing with a NativeScript Core project, too; that's useful information.

shirakaba commented 5 years ago

A quick thought (note to myself): TypeError: undefined is not an object (evaluating 'o[Symbol.iterator]') makes me think that the React Host Config may be trying to iterate over an array of children or some other array-like property on the Page, but that array is found to be undefined. But maybe it's something else entirely.

Lelelo1 commented 5 years ago

There is no problem when adding the SegmentedControl manually in componentDidMount to the layout.

There is an items array property on the component - so it is not intended to take children I believe. Also there is no $SegmentedBarItem to declare in the tsx - and to give to $SegmentedBar.

shirakaba commented 5 years ago

There is an items array property on the component - so it is not intended to take children I believe.

The Host Config supports the addition of SegmentedBarItem children, but as you say, it seems I haven't implemented a $SegmentedBarItem React component, so the feature's incomplete right now. Sorry about that, I'll add one.

Sounds like I'd better run the repro and see what needs implementing in the library. Hopefully I'll have some time to do that this evening.

Lelelo1 commented 5 years ago

Again, the error is thrown from simply declaring $SegmentedBar anywhere.

So if page and frame is removed in AppContainer and replaced with $SegmentedBar (only) - the error is thrown:

render() {
    return(
        <$SegmentedBar />
    );
}

There is no error about failed to create page etc - or crash beacuse there is no frame.

shirakaba commented 5 years ago

I've identified a fix for the issue; will create a $SegmentedBarItem component as well before pushing the patch.

shirakaba commented 5 years ago

Issue closed in version 0.11.0 – see my example SegmentedBar code snippet. Thanks for the report!

SegmentedBar fixed