Is there any differences between the following two ways of defining defaultProps in React?
class ReactComp extends React.Component {}
ReactComp.defaultProps = {}
OR
class ReactComp extends React.Component {
static defaultProps = {}
}
They are no different. They both are static in nature. The first one is the Property provided by React defaultprops if you are using the ES6 class syntax and the other one is to declare the props in the ESNext way. (nothing to do with React).
You can find more info on the static keyword on MDN.
Related
Beginner question struggling with React Component implementation.
I have tried everything in the cookbook on this error but no luck.
Expected 'this' to be used by class method 'aaaa'
What is wrong with his code:
import React from 'react';
class TestStuff extends React.Component {
constructor(props) {
super(props);
this.aaaa = this.aaaa.bind(this);
}
aaaa() {
console.log('dddddd');
}
render() {
return <div>test</div>;
}
}
export default TestStuff;
The warning is just saying, I see that you have this method in this class but it's not using any properties in the class. So either make it a static method or access a class property inside the method.
https://eslint.org/docs/rules/class-methods-use-this
I am looking at an older React class that is written in JS. The class in JS references 'this.element' which is not something that intrinsically exists in a typescript class that extends React.Component. I'd love some direction on what 'this.element' is referencing and how to use it in the new TS Component model. TYIA
You need to define the property on the class:
class SlideDownTransition extends React.Component {
element: React.Component;
/*...*/
}
I'm trying to bring Typescript into a project that extends react components with various additional class properties. I'm trying to work out how to extend the React.Component type to incorporate those additional attributes.
As an example of what I mean, in both class and functional form:
class SampleComponent extends React.Component<{}, {}> {}
const OtherComponent: React.SFC<{}> = (props) => <div/>
SampleComponent.importantClassProp = "Hello StackOverflow"
OtherComponent.importantClassProp = "I need help."
The closest I've been able to get thus far has been the following, which only works for purely functional components and makes the additional prop optional (since it's technically set after component declaration, making the attribute mandatory would be amazing).
interface SpecialComponent<P = {}> extends React.StatelessComponent<InputProps & P> {
specialKey?: string;
}
const Component: SpecialComponent<{}> = props => <div/>
Component.specialKey = "Yo"
So I have a BaseComponent.jsx that I extend on many of my components. This works great.
class BaseComponent extends React.Component {
constructor(props){
super(props)
this.something = true
}
}
class OtherComponent extends BaseComponent {
constructor(props){
super(props)
console.log(this.something) // true
}
}
But now I need to use withRouter(component) from react-router which wraps your component in a higher order component and decorates your class.
So I do this:
class OtherComponent extends BaseComponent {
constructor(props){
super(props)
console.log(this.something) // undefined
}
}
export default withRouter(OtherComponent)
The problem is that now I can't access the properties from BaseComponent and those return undefined.
How can I solve this so that I can create a HoC and at the same time access the properties of the base class?
Extending React components is discouraged by the React team. Even if it works on some instances, the results are unpredictable when doing fancier things such as higher order components.
General extending component classes should be avoided, and even if used, should not be used on "smart" connected components anyway – prefer composition over inheritance for React components.
And
You cannot implement a generic HoC that extends a component for the simple reason that the HoC has to work with all three forms of React component declaration.
Source: https://github.com/reactjs/react-router/issues/3514
So the answer to my question is simply that it can't be done and I should move to composition instead of inheritance.
I'm using a library which isn't written in TypeScript and thus I've to use the definition file.
Within this definition file there's a class without a constructor (because the original JS code doesn't have a constructor). If I try to extend the class within my code, I get the error:
Error:(36, 2) TS2377: Constructors for derived classes must contain a
'super' call.
If I add super() to the constructor, JavaScript complains:
Uncaught TypeError: _super.call is not a function
How can I modify the definition file so that this code works and the first error from TS is eliminated? (for TypeScript 1.6)
Here's a simple example of the definition file (based on backbone-global.d.ts:
declare module Backbone {
class Events {
on(eventName: string, callback?: Function, context?: any): any;
off(eventName?: string, callback?: Function, context?: any): any;
}
class ModelBase extends Events {
...
}
class Router extends Events {
...
}
}
Within my code I have something like:
/// <reference path="libs/typescript/backbone/backbone.d.ts" />
class RosApiManager extends Backbone.Events {
constructor() {
super();
}
}
Backbone.events is not a class (and should not have been declared as such in the .d.ts file). You can't extend something that isn't a class.
Some might the error:
_super.call is not a function
if they incorrectly defined the class like
export class InlineIf extends React{... }
instead of
export class InlineIf extends React.Component {... }
Adding this as an answer hoping someone might find it useful in the future...