-
Notifications
You must be signed in to change notification settings - Fork 72
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Help Request: React component is checking for a prop when it is created, but the prop doesn't appear to be supplied until later #124
Comments
I tried to reproduce but it didn't reproduce for me. What I did: I modified the ReactDot test component to have a required prop and for good measure added a special error in the constructor if the prop was not passed. Then I added the prop in the Angular template. I didn't get any errors. Here's my code:
The |
I am able to reproduce the error if I populate the
and
|
Thanks for the help! I'm away for a few days, as soon as I'm back I'll try and dig deeper for some more details. I'll put your sample into my setup too and see if it generates any errors.
…On 12 Jun 2019, 10:12 pm, at 10:12 pm, Aaron Greenwald ***@***.***> wrote:
I tried to reproduce but it didn't reproduce for me. What I did: I
modified the ReactDot test component to have a required prop and for
good measure added a special error in the constructor if the prop was
not passed. Then I added the prop in the Angular template. I didn't get
any errors. Here's my code:
```
// tslint:disable:no-input-rename
// tslint:disable:no-output-rename
import {
Component,
ChangeDetectionStrategy,
Input,
Output,
EventEmitter,
ElementRef,
ViewChild,
ChangeDetectorRef,
Renderer2,
NgZone,
} from ***@***.***/core';
import * as React from 'react';
import * as PropTypes from 'prop-types';
import { ReactWrapperComponent } from ***@***.***/core';
@component({
selector: 'app-react-dot',
template: `
<ReactDot
#reactNode
[text]="text"
[foo]="'bar'"
(onMouseEnter)="onMouseEnter($event)"
(onMouseLeave)="onMouseLeave($event)"
[styles]="{
width: size,
lineHeight: size,
height: size,
left: x,
top: y,
color: color,
backgroundColor: backgroundColor,
fontSize: size
}"
>
<react-content> <ng-content></ng-content> </react-content>
</ReactDot>
`,
changeDetection: ChangeDetectionStrategy.OnPush,
styles: ['react-renderer'],
})
export class ReactDotComponent extends
ReactWrapperComponent<ReactDotProps> {
@ViewChild('reactNode') protected reactNodeRef: ElementRef;
@input() x: string;
@input() y: string;
@input() size: string;
@input() text: string;
@input() color: string;
@input() backgroundColor: string;
@input() textOverride: string;
@output('onMouseEnter') readonly mouseEnter = new
EventEmitter<MouseEvent>();
@output('onMouseLeave') readonly mouseLeave = new
EventEmitter<MouseEvent>();
onMouseEnter = (ev: MouseEvent) => this.mouseEnter.emit(ev);
onMouseLeave = (ev: MouseEvent) => this.mouseLeave.emit(ev);
get computedText() {
return this.textOverride && this.text ? this.textOverride : this.text;
}
constructor(elementRef: ElementRef, changeDetectorRef:
ChangeDetectorRef, renderer: Renderer2, ngZone: NgZone) {
super(elementRef, changeDetectorRef, renderer, { ngZone,
setHostDisplay: true });
}
}
interface ReactDotProps {
onMouseEnter?: (ev: MouseEvent) => void;
onMouseLeave?: (ev: MouseEvent) => void;
text: string;
foo: string;
styles?: object;
}
export class ReactDot extends React.Component<ReactDotProps> {
private static defaultStyle = {
display: 'block',
position: 'absolute',
textAlign: 'center',
borderRadius: '30%',
cursor: 'pointer',
};
static propTypes = {
foo: PropTypes.string.isRequired
}
constructor(props) {
super(props);
if (!props.foo) {
throw new TypeError('ReactDot requires a foo prop');
}
}
render() {
const { text, styles, foo, ...rest } = this.props;
return React.createElement(
'div',
{
...rest,
style: {
...ReactDot.defaultStyle,
...styles,
},
},
[this.props['text'], ...(this.props.children as any)]
);
}
}
```
The `foo` prop is the one I added.
--
You are receiving this because you authored the thread.
Reply to this email directly or view it on GitHub:
#124 (comment)
|
Hi, Sorry for the delay in getting back to you. I think I have reduced this down to some interactions with another component on the same parent page. I moved the other components initialisation into ngAfterViewInit instead of ngOnInit, then all the errors went away. Digging deeper, the other component is manipulating some DOM (and from what I can tell it is throwing and catching some errors, so usually they don't see the light of day, it all happens internally). This is triggering a zone.js callback by the looks, which is turn is calling the react component, which hasn't initialised yet. (I was originally running this other component outside of the Angular zone, however that seemed to mess up the stack trace and not show where the triggering change that was causing the error). This is a 3rd party component that is minified, so it's a bit hard to follow. To reproduce the issue: On the page that holds the react component, add another angular component alongisde it. In that angular component, in the ngOnInit, throw an error while outside the angular zone like this:
This isn't quite the same, because in the original case the error never reaches the console if you run it in isolation, it's only when you run it alongside the react component with a required prop. I hope this makes some sense! I'm still trying to get a reproducible isolated case sorry. |
This is the call stack
You'll notice the DlhSoft file in the stack trace. This is what is triggering the issue. |
Ok, I have a much better test case! Add a component like this next to the wrapped react component. So the parent component looks like this (pseudocode)
AppComponent looks like this
Running the change detection cycle during the OnInit seems to be what is triggering the error. |
This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. Thank you for your contributions. |
Hi!
I'm trying to create a wrapper around a React component to use within Angular. I haven't done much with React before, so that side of things is quite new to me.
I'm getting an error that a prop is required, but I am supplying that prop.
I had a look and the component is expecting a prop to be set when it is created. However it appears that in Angular-React, the property is supplied later.
The component still works, but it logs a whole lot of errors before it starts working.
The error is like this:
The code that is throwing the error is this:
In my template I have (This is slightly simplified, there are multiple related components in there)
And fetch is a function in the class (and it is being called)
So I am just wondering if I am doing anything incorrectly, or is there a way I can supply the fetch prop earlier on to avoid the error?
Thanks!
Ryan
The text was updated successfully, but these errors were encountered: