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

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.

Related

what is class extends React.component in React

In this link https://reactjs.org/docs/higher-order-components.html
where explanation is of higher order component.The code is below has class extends React.component. What is this class keyword here?
function logProps(WrappedComponent) {
return class extends React.Component {
componentDidUpdate(prevProps) {
console.log('Current props: ', this.props);
console.log('Previous props: ', prevProps);
}
render() {
// Wraps the input component in a container, without mutating it. Good!
return <WrappedComponent {...this.props} />;
}
}
}
It is an unnamed class expression.
return class extends React.Component {
The above code is creating an unnamed / anonymous class by extending React.Component class, hence, creating a new React Component which wraps (returns) the WrappedComponent passed to the function logProps.
The syntax of class expression is:
const MyClass = class [className] [extends otherClassName] {
// class body
};
where the name className (and also, extends otherClassName) is optional.
And, in your code in question, it is just returning the result instead of assigning it to a variable:
return class [className] [extends otherClassName] {
// class body
};
Note that, there are two ways to create a React Component, one is by writing a function and the other is by writing a class.
And, in JavaScript, classes was introduced in ECMAScript 2015 (also knows as ES6).

Where does "this.state" comes from when using TypeScript in React

I was wondering where does the property this.state comes from when using React with TypeScript?
public constructor(props: any) {
super(props);
this.state = {
userName:"Code to html, one way -->",
password:""
};
}
We are not importing it in the super() call, so where does it comes from?
It comes from the internal implementation of React component which you inherit by extending the class React.Component:
class MyComponent from React.Component {
// this.setState, this.state,
// lifecycle methods and more
}
See React.Component and its instance properties.
where does it comes from?
It comes from the constructor. The line you are asking about is exactly where this.state is initialized.

Different ways to initialize the state in ReactJS

It might be because of the speed that ReactJS is developing, or just some mis-information, but when reading articles about how to set the state, I usually come across different ways.
In the constructor
class MyComponent extends React.Component {
constructor(props) {
super(props);
this.state = { ... }
}
}
Directly in the class
class MyComponent extends React.Component {
state = { ... }
}
In ComponentWillMount
class MyComponent extends React.Component {
ComponentWillMount() {
this.state = { ... }
}
}
This diversity of options confuses me often, and makes it hard for me to decide how I should set the state in my components.
My question is: Is there any difference between these methods to set the state? If so, what are the advantages and disadvantages of each?
These are all basically the same thing, just syntactic sugar.
In the constructor
This is the "normal" standard way to attach a property to a class instance.
Directly in class
This is just a syntactic sugar and this is the class fields proposal which is in stage 3 at the moment (01/10/18). you will need babel/plugin-proposal-class-properties
In ComponentWillMount
Same as the constructor version but inside a life-cycle method of react (which is deprecated by the way).
You should now componentWillMount is deprecated and you should not use it. as for setting the state in the constructor or as class property is the same you can use either, I prefer the class property.
This is class field proposal:
class MyComponent extends React.Component {
state = { ... }
}
It is syntactic sugar for:
class MyComponent extends React.Component {
constructor(props) {
super(props);
this.state = { ... }
}
}
The former is shorter and can be considered preferable in transpiled React application because of its brevity, unless there's a need for explicit constructor.
ComponentWillMount lifecycle hook was renamed to UNSAFE_componentWillMount and deprecated in favour of constructor:
UNSAFE_componentWillMount() is invoked just before mounting occurs. It is called before render(), therefore calling setState() synchronously in this method will not trigger an extra rendering. Generally, we recommend using the constructor() instead for initializing state.

Do the constructors of React Components need the props argument?

Should I include the props argument in the constructor and call to super if I am not using props at all for a component?
For example, if I write:
class NotePage extends React.Component<void, State> {
constructor(){
super();
this.state = {
filterStr: "string"
};
}
...
}
Will this cause any issues?
I'm asking because if I include props then flow complains about a missing annotation and one way to solve the problem is to remove the props argument.
From official docs React Constructor
you should call super(props) before any other statement. Otherwise, this.props will be undefined in the constructor, which can lead to bugs
constructor(props) {
// no super call
}
If you don't call it, the data passed from parent as properties is not available inside child component's constructor with props. Props will, however, still be available in the rest of the component, such as the render function.
e.g.
class Parent extends React.Component{
render(){
return (<Child mydata = {'some data here'}/>)
}
}
class Child extends React.Component{
constructor(){
super(); //no props
this.props.mydata //will be undefined
}
render(){
this.props.mydata //defined
}
}
First of all you don't need constructor function at all, when you are not accessing props in initialization of component. You can write your state this way:
class NotePage extends React.Component<void, State> {
state = {
filterStr: "string"
}
...
}
Only when you are using props for initialization you need to , make use of constructor and call this way:
class NotePage extends React.Component<void, State> {
constructor(props){
super(props);
this.state = {
filterStr: "string"
};
}
...
}
Hope this helps !!
I found a great link written by #dan Abramov (react core team). this also might help people understanding super(props). Link

React + Typescript: Type of React component with no state/no props

I've seen multiple examples of React components using Typescript:
class Foo extends React.Component<IProps, IState> {}
It seems there is no a clear convention when we don't use either the Props or the State.
People set these types as any, null,undefined,{}, void, etc.This is what I've seen so far:
class Foo extends React.Component<null, null> {}
class Foo extends React.Component<any, any> {}
class Foo extends React.Component<{}, {}> {}
class Foo extends React.Component<undefined, undefined> {}
class Foo extends React.Component<void, void> {}
class Foo extends React.Component<object, object> {}
What's the best way of doing it?
Update:
Props:
void cannot be used (https://github.com/Microsoft/TypeScript/issues/15409 and https://github.com/Microsoft/TypeScript/issues/15419 ) as the props object is initialised to {}
SOLUTION
Simply do - class Foo extends React.Component {} as prop and state are initialised to {}
As answered for this question, you can use the React.FC<{}> class
const MyStatelessComponent : React.FC<{}> = props =>
<div>{props.children}</div>
Or if your markup gets bigger:
const MyStatelessComponent : React.FC<{}> = props => {
{/* Some code here */}
return <div>{props.children}</div>
}
From https://github.com/DefinitelyTyped/DefinitelyTyped/blob/15b7bac31972fbc081028937dfb1487507ca5fc9/types/react/index.d.ts#L199-L200
interface Component<P = {}, S = {}> extends ComponentLifecycle<P, S> { }
Props and state are initialised to {}, so for a component with no state nor prop we can simply do:
class Foo extends React.Component {}
According to this guideline and my exp, I would say :
class Foo extends React.Component<null, null> {} when you know you will not recieve props nor state
class Foo extends React.Component<any, any> {} when you know you will recieve props and state but you really don't care what they look like
class Foo extends React.Component<{}, {}> {} never saw, seems strange
class Foo extends React.Component<undefined, undefined> {} same as null, it's up to you. I see more often null than undefined
class Foo extends React.Component<void, void> {} bad idea, since seems to be reserved for functions return (when you do not expect one)
Other opinions are welcomed
You can use VoidFunctionComponent for stateless ans propless components (without state ana props):
const MyComponent: React.VoidFunctionComponent = () => {
...
}
I always create a props Interface for each component, even if it's blank. It keeps things consistant and allows me to easily add props later if needed.
Interface FooProps { }
class foo extends React.Component<FooProps, any> {
}
Stateful(class based components) & Stateless components there's a lot of conceptions on the internet about when use one or another, I've grasped these concepts using this list (before have practical experience):
Stateless
Are concerned with how things look.
May contain both presentational and container components** inside,
and usually have some DOM markup and styles of their own.
Often allow containment via this.props.children.
Have no dependencies on the rest of the app, such as Flux actions or
stores.
Don’t specify how the data is loaded or mutated.
Receive data and callbacks exclusively via props.
Are written as functional components
Examples: Menu, UserInfo, List, SideBar.
Stateful
Are concerned with how things work.
May contain both presentational and container components** inside
but usually don’t have any DOM markup of their own except for some
wrapping divs, and never have any styles.
Provide the data and behavior to presentational or other container
components.
Call Redux actions and provide these as callbacks to the
presentational components.
Examples: UserPage, FollowersSidebar, ArticlesContainer.

Resources