Babel 6 making super constructor call to parent throws exception - reactjs

I upgraded to babel version 6 and I am using "es2015", "react", "stage-0" as presets. I am working with react using es6 syntax.
Everything was working fine until the upgrade. After the upgrade I started to get exceptions in places where I make super call to parent constructor.
For example for the following class:
class childForm extends ParentForm {
constructor(props, context) {
console.log("this get printed.");
super(props, context);
console.log("this is not printed");
}
...
}
class ParentForm extends React.Component {
constructor(props, context) {
console.log("this is printed");
super(props, context);
console.log("this is printed too");
}
...
}
class AnotherComponent extends React.Component {
constructor(props) {
super(props);
this.state = {};
myService.findById(this.props.params.id).then(result => {
this.setState({result: result});
}).catch(err => {
/**** Error is catched here ******/
console.log(err);
});
}
render(){
return <div>{this.state.result && <ChildForm/>}</div>
}
}
I got the following errors on the console:
TypeError: (0 , _typeof3.default) is not a function(…)
ReactCompositeComponent.js?cd59:443 Uncaught (in promise) TypeError: Cannot read property 'context' of null(…)
React function that throws the error is the following function. The exception raised at ReactCompositeComponentMixin.updateComponent
updateComponent: function (transaction, prevParentElement, nextParentElement, prevUnmaskedContext, nextUnmaskedContext) {
var inst = this._instance;
var nextContext = this._context === nextUnmaskedContext ? inst.context : this._processContext(nextUnmaskedContext);
....
If I carry all the functionalities of the parent class to child class, it works as expected. Do anyone encountered a similar problem?
Also is it possible to have better exception messages using some library or plugin for react?

This might be an issue around class compilation. It looks like it can cause an error currently if the child class is declared before the superclass.
Trying this on babeljs.io currently results in an error:
class A extends B {
constructor(x) {
super(x);
}
}
class B {
constructor(x) {
console.log(x);
}
}
new A('a');
Try changing the order of the class definitions:
class ParentForm extends React.Component {
constructor(props, context) {
super(props, context);
}
...
}
class childForm extends ParentForm {
constructor(props, context) {
super(props, context);
}
...
}
EDIT: It seems that Chrome's classes behave pretty much the same, Uncaught ReferenceError: B is not defined(…) is thrown at declaration.

Installing babel-runtime#6.3.19 should solve the problem. Checkout the issue https://phabricator.babeljs.io/T6644

Related

Class Component with new kotlin-react without legacy

The kotlin-wrappers for React was split into kotlin-react and kotlin-react-legacy in version pre.282.
In kotlin-react-legacy it is possible to create a class based component by using RComponent.
This is missing in the new kotlin-react, however both kotlin-react and kotlin-react-legacy import kotlin-react-core which contains Component.
In kotlin-react-legacy the RComponent is defined by using RBuilder, but that doesn't exist in kotlin-react which instead has ChildrenBuilder. It would be possible to create something analogous to the legacy RComponent with ChildrenBuilder, however it cannot be accessed because it is internal.
Is there any way to create a class-based React Component, similar to what is possible in kotlin-react-legacy with RComponent, in the new kotlin-react?
There is a related discussion: https://github.com/JetBrains/kotlin-wrappers/issues/1266
Which mentions a working example: https://github.com/studoverse/campus-qr/blob/master/moderatorFrontend/src/main/kotlin/webcore/ReactHelper.kt
The RComponent can be defined as follows:
abstract class RComponent<P : Props, S : State> : Component<P, S> {
constructor() : super() {
state = jso { init() }
}
constructor(props: P) : super(props) {
state = jso { init(props) }
}
open fun S.init() {}
// if you use this method, don't forget to pass props to the constructor first
open fun S.init(props: P) {}
abstract fun ChildrenBuilder.render()
override fun render(): ReactNode = Fragment.create { render() }
}
fun <S : State> Component<*, S>.setState(buildState: S.() -> Unit) {
setState({ assign(it, buildState) })
}
Then a component can be created as:
class TestComponent : RComponent<Props, State>() {
override fun ChildrenBuilder.render() {
div {
+"Hello, world!"
}
}
}
And instantiated:
TestComponent::class.react {}

React: How to read state from within handler function?

I'm new to React working on an existing React component (that appears to be built in an older style - no hooks).
I want to read and set state within a handler function. I have the following code:
export default class MyComponent extends React.Component {
static defaultProps = {
data: {}
};
constructor(props) {
super(props);
// Other states
this.state.myState = false;
};
handleMyChange() {
if (!this.state.myState) {
console.log("hello world");
}
}
However I get the error Cannot read properties of undefined.
I've tried various like state.myState but am not really sure what I should be doing.
Can anyone point me in the right direction?
In order to have this context in your function, you will need to bind it in the constructor first
Here is a small example is taken from the official doc:
import React from "react";
export default class SayHello extends React.Component {
constructor(props) {
super(props);
this.state = { message: "Hello!" };
// This line is important!
this.handleClick = this.handleClick.bind(this);
}
handleClick() {
alert(this.state.message);
}
render() {
// Because `this.handleClick` is bound, we can use it as an event handler.
return <button onClick={this.handleClick}>Say hello</button>;
}
}

ReactJS - Unexpected token '.' error

I am starting with my react project on VS2013 working together with ASP.NET MVC. I have configured webpack and configuration seemed working well until I tried to implement the following class.
class Hello extends React.Component {
this.state = { visible: true }
render() {
/** Method definition **/
...
}
I am getting an error Unexpected Token at '.' at 'this.state'. I have already check es2015 is set as babel preset. If I remove state and toggleVisibility assignments, webpack bundles OK.
Any idea what else can I try?
It's a class so the correct syntax should be
class Hello extends React.Component {
state = { visible: true }
render() {
/** Method definition **/
...
}
Also, the recommended way of defining initial state should be
class Hello extends React.Component {
constructor(props) {
super(props)
this.state = { visible: true }
}
render() {
/** Method definition **/
...
}
You should define this.state in a constructor like
constructor(props) {
super(props);
this.state = {
visible: true
};
}
Hence, your code should be
class Hello extends React.Component {
constructor(props) {
super(props);
this.state = {
visible: true
};
}
render() {}
}
From React docs:
The constructor is the right place to initialize state. If you don't
initialize state and you don't bind methods, you don't need to
implement a constructor for your React component.

console.log & debugger statements in React.Components - unexpected token

What is the proper way to add console.log and debugger statements to my React.Components?
Just dropping them in produces Unexpected token errors:
export class ManageCoursePage extends React.Component {
debugger;
constructor(props, context) {
super(props, context);
A little more helpful but still produces Unexpected 'debugger' statement:
export class ManageCoursePage extends React.Component {
constructor(props, context) {
super(props, context);
debugger;
Or even browsers' console errors out Uncaught SyntaxError: Unexpected token ;:
class Woot {
debugger;
}
What exactly is going on here?
Move your debugger statement inside the constructor or a function and it'll work fine.

ReactJS - ES6 class - call super() with augmented properties

This is what I would like to do:
constructor(props, store) {
props.store = store;
super(props);
};
I get the following error:
Uncaught TypeError: Can't add property store, object is not extensible
I understand that properties are immutable in ReactJS. So how can I clone, then augment the existing properties?
UPDATE 1
Some background: I'm basically trying to avoid a this._store "private" variable, and would rather have it in the props, since the value is known at object creation time and will not change.
My class hierarchy is as follows:
import SpeakersStore from ...;
class SpeakersViewController extends ItemsViewController {
constructor(props) {
super(props, SpeakersStore);
};
...
};
class ItemsViewController extends React.Component {
constructor(props, store) {
props.store = store;
super(props);
};
...
};
You should be able to do the following:
constructor(props, store) {
super({...props, store});
}
If you're in an environment where the object spread operator (the {...props} construct) is not available, then you can use Object.assign:
constructor(props, store) {
super(Object.assign({}, props, {store});
}
However, if this is a constructor for a React component, be aware that the second argument to the constructor for React.Component is context, and you won't get the behavior you're looking for.

Resources