use lifecycle in child component in react - reactjs

I'm implementing an inherit action to archive my goal.
My goal is to call a lifecycle event in child component instead of parent one. That's what I can do in C# .net. How can I archive it? Is there any difference?
When I call lifecycle event in parent component, it works fine
Here's my code
class A extends React.Component {
render() {
return (
//......
)
}
}
class B extends A {
componentDidMount() {
console.log('componentDidMount') // didn't log here
}
componentDidUpdate(prevProps) {
console.log('componentDidUpdate:', prevProps) // didn't log here
}
}
Thanks all

This is quite tricky.
In JavaScript, a class cannot extend from multiple classes, which is also known as “multiple inheritance”. In JavaScript, objects can only be associated with a single prototype, and extending multiple classes would mean that an object associates with multiple prototypes, which is not possible.
Also, to have lifecycle methods, the class should extend React.Component.
So you can either extend React.Component or Component A.

Multiple inheritance doesn't allow in javascript by the time I'm writing this. And life-cycle event will work only if you extends React.Component. So, you should not extends another component in react. The recommended way is - use composition pattern instead of inheritance.
import B from './B';
class A extends React.Component {
render() {
return (
<B />
//.......
)
}
}
class B extends React.Component {
componentDidMount() {
console.log('componentDidMount')
}
componentDidUpdate(prevProps) {
console.log('componentDidUpdate:', prevProps)
}
}
Now it will work. Hope you will figure out the problem. For more please visit reactjs composition vs inheritance

the trick is to use super.componentDidMount() in the child component
componentDidMount() {
super.componentDidMount();
console.log('componentDidMount')
}
here you can find the working code
https://codesandbox.io/s/crazy-snow-1k9t2?file=/src/App.js

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).

What is the difference between Higher Order Component (HOC) and Inheritance in React native component

I am new to react native from .net background,
Here the Question is how HOC is different from inheritance in OOPS concept by having a parent class with base properties and child that extends the Base and use the state, properties and base methods from the Base class.
Which is the best way to achieve the Parent-> Child -> GrandChild hierarchical relationship in React Components .?
For Example:
Parent.js Looks like
class Parent extends Component
{
constructor(props)
{
super(props);
this.state = {
value: "Parent",
BaseText: "Inheritance Example"
}
}
onUpdate = () => {
console.log("Update called at Parent")
}
}
Child.js which extends Parent.js
class Child extends Parent
{
constructor(props)
{
super(props);
//this state should inherit the properties of Parent and override only the value property
this.state = {
value: "Child",
}
}
onUpdate = () => {
super.onUpdate();
console.log("Update called at Child view")
}
render()
{
return(
<View>
<Text> Child View</Text>
</View>
)
}
}
The GrandChild.js extends from Child.js
class GrandChild extends Child
{
constructor(props)
{
super(props);
//this state should inherit the properties of Child, Parent and properties specific to this
this.state = {
value: "GrandChild",
Name: "Test Grand Child"
}
}
onUpdate = () => {
super.onUpdate();
console.log("Update called at Grand Child view")
}
render()
{
return(
<View>
<Text> Grand Child View</Text>
</View>
)
}
}
Is this the right way of implementing abstraction in react native
say Parent class will have the common state properties and the child inherits the Parent state and has its own properties.
How to inherit state and how to update values to state in this case .?
React promotes composition as an alternative to class inheritance. Components were designed to be efficiently composed. Hooks API augments function components with features that previously required class components to be used.
This doesn't mean that inheritance isn't allowed. The problem with it is that existing patterns such as higher-order component are widely used in React ecosystem and aren't compatible with OOP:
const withBaz = Comp => <Comp baz />
#withBaz
class Bar extends Foo { ... }
This approach is common but it isn't OOP friendly because in this case Bar is actually not a class anymore but arrow function, it cannot be inherited further.
There are no problems with using OOP for first-party React components as long as a developer controls all components in class hierarchy, but this may be unpractical because there always may be a need to involve third-party code that isn't OOP-friendly. The use of composition where it fits results in more flexible design.

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.

The this keyword is undefined in React base class

I have a basic React app and I'd like to put some commonly used functionality into a base component class and have all my other components inherit from that class to get access to those features. I have this:
export class BaseComponent extends React.Component {
constructor() {
super();
this.commonlyUsedMethod = this.commonlyUsedMethod.bind(this);
}
commonlyUsedMethod() {
let x = this.someValue; // <--- 'this' is undefined here
}
}
export class SomeComponent extends BaseComponent {
onButtonClick() {
super.commonlyUsedMethod();
}
render() {
return whatever;
}
}
The problem is that when I call super.commonlyUsedMethod() from the derived class, this.someValue blows up inside BaseComponent.commonlyUsedMethod() because this is undefined. I'm calling this.commonlyUsedMethod.bind(this); in the BaseComponent constructor, so I'm not sure what's going on.
First of all I (and most of the React dev community) don't recommend you to use inheritance. https://facebook.github.io/react/docs/composition-vs-inheritance.html
Most of the use cases you have you can solve it using Higher Order Components or writing functions in a JS file and importing it.
If you still want to go ahead and do this.
You need to bind the this when you attach the buttonClick listener
export class SomeComponent extends BaseComponent {
onButtonClick() {
super.commonlyUsedMethod();
}
render() {
return <div onClick={this.onButtonClick.bind(this)}>Hello</div>;
}
}
Here is the working example for it. https://www.webpackbin.com/bins/-Knp4X-n1RrHY1TIaBN-
Update: Problem was not with calling super with proper this, problem was with not binding proper this when attaching the onClick listener. Thanks #Mayank for pointing it out.
So I'm not sure if this a Good Practice™, but I can get it to work by calling this.someCommonMethod() instead of super.someCommonMethod(), like this:
export class SomeComponent extends BaseComponent {
constructor() {
super();
this.onButtonClick = this.onButtonClick.bind(this);
}
onButtonClick() {
this.commonlyUsedMethod(); <--- changed 'super' to 'this'
}
render() {
return whatever;
}
}
I'm new enough to React and ES6 not to know if this is how this should work. Any thoughts would be appreciated.

Subclassing react components, HOC or classic OO?

I am in the process of writing a React application which is responsible for rending content from an external CMS.
Content is pulled from the CMS into a redux store when the application first loads and is accessed via connected components or props throughout its life-cycle.
I need certain methods to be available across all components making use of CMS'd content.
After researching the "React" way of achieving this, it seems the following way is generally frowned upon whilst using higher order components is viewed as a better practice. Coming from an OO background, I'm struggling to understand why?
For example...
import React, { Component } from 'react';
class CMSComponent extends Component {
constructor(props) {
super(props);
}
mySharedMethod(path) {
// Assume CMS content is located in this.props.content unless otherwise stated
// Please be aware that the actual code has been simplified massively for the sake of the question
return this.props.content[path]
}
}
I now have a base class that all my CMS components can inherit from, like so...
import CMSComponent from './components/cms'
class Page1 extends CMSComponent {
constructor(props) {
super(props);
}
render() {
// mySharedMethod() inherited from base class
return <div>{ this.mySharedMethod(['data', 'intl', 'my-keyed-content']) }</div>
}
}
If anyone could shed any light on why this is considered incorrect I would be extremely grateful.
For reference, I guess the same scenario using HOC would look something like this...
import React, { Component } from 'react'
export default function CMSInject(ChildComponent) {
class CMSComponent extends Component {
constructor(props) {
super(props);
}
mySharedMethod(path) {
return this.props.content[path]
}
render() {
return <ChildComponent {...this.props} {...this.state} /* and some refs */ />
}
}
return CMSComponent
}
...then export the child via the higher order parent component...
import React, { Component } from 'react'
class Page1 extends Component {
constructor(props) {
super(props);
}
render() {
// mySharedMethod() still inherited from base HOC class
return <div>/* CMS BASED CONENT HERE */</div>
}
}
export default CMSInject(Page1)

Resources