How to replace useEffect hook with component lifecycle? - reactjs

I'm forced to use class based component, so how can I replace useEffect with component lifecycle like componentDidMount, componentDidUpdate and componentWillUnmount in my React component.
Please help
const App = () => {
useEffect(() => {
store.dispatch(loadUser());
}, []);

As React team mentioned in this doc
Hooks are a new addition in React 16.8. They let you use state and other React features without writing a class.
So if you want to use life cycles you have to use class
.
Use class that extends Component and it must be like this :
import React from 'react';
class App extends React.Component {
//you can use components lifecycle here for example :
componentDidMount() {
store.dispatch(loadUser());
}
}

After delcaring the constructor you should put the componentDidMount method just ahead, like this:
class yourComponent extends Component {
constructor(props){
// constructor taks...
}
componentDidMount() {
// what you want to do when the component mount
}
}

Related

How do I update state of parent class where Ive defined contexAPI , when I submit a form in child component?

How do I update state of the class where parent contex api is defined , when I submit form from a child component ??
import React, {createContext,Component} from 'react'
import http from './services/httpService'
import {MyApiUrl} from './services/httpService'
export const GlobalState = createContext()
export class DataProvider extends Component{
state={
jobs:[],
loadstate:false,
}
async populateCategories() {
const {data:jobs}=await http.get(MyApiUrl+'/api/jobs')
this.setState({jobs})
console.log('hellow world')
return
}
async componentDidMount(){
await this.populateCategories()
}
logPokemon = this.populateCategories.bind(this);
// async setUser() {
// await this.populateCategories()
// }
render(){
const {jobs}=this.state;
const{logPokemon}=this
const{children}=this.props
return (
<GlobalState.Provider value={{logPokemon,jobs}}>
{children}
</GlobalState.Provider>
)
}
}
now from another child component , when a form is submitted I did this , And I got a Warning: Can't perform a React state update on an unmounted component
static contextType = GlobalState
const {logPokemon} = this.context;
logPokemon()
Only Call Hooks from React Functions. Class components don't support hooks - Hooks-FAQ
You can’t use Hooks inside of a class component, but you can
definitely mix classes and function components with Hooks in a single
tree. Whether a component is a class or a function that uses Hooks is
an implementation detail of that component. In the longer term, we
expect Hooks to be the primary way people write React components.
You can not use createContext hooks or any other react hooks in the class base component. Hooks are only used in the functional components. Learn more about hooks

Call a method in another Component that returns some value in React

I am having two independent components in react and I want to call a method in first component that returns Some value to another component.
import React from 'react';
export default class A extend React{
constructor(props){
super(props);
}
getName = () =>{
var name = "MyName";
return name;
}
render(){
//Some code to render
}
}
Now In component B in want to call method getName() so that it returns name,which i want to use in component B.
import React from 'react';
export default class B extends React{
constructor(props){
super(props);
}
getName = () =>{
//Want to call the getName method of component A here
}
render(){
//Some code to render
}
}
Use React lifting State Up.
Here is the official documentation.
Lifting State Up

Extend React lifecycle hook (e.g add a print statement on every ComponentDidMount)

I want to add some behaviour on a given lifecycle hook of a React application.
For example, adding a console.log('Component is mounted') on every ComponentDidMount of all the components of an application, without having to define it in every one of them (as a decorator for example), sort of like a global extender of that method that adds some code to it. Like that: Extending Vue Lifecycle Hooks but for React.
Anyone has an idea on how to achieve that? Cheers!
You can use hoc. In the root app, apply the higher order component.
Example:
const withMountHOC = WrappedComponent => {
return class extends Component {
componentDidMount() {
console.log('mounted');
}
render() {
return <WrappedComponent {...this.props} />
}
}
}
export default withMountHOC;
In your app component:
const WrappedApp = withMountHOC(App);
ReactDOM.render(
WrappedApp,
document.getElementById('root')
);
Since the parent componentDidMount hook is called after child componentDidMount hook, the HOC componentDidMount will be applied in any nested level of the component.
You may also be interested to see this blog: Replacing Mixins in React.
create CustomComponent.js
import React, { Component } from 'react'
class CustomComponent extends Component {
constructor(props){
super();
}
componentDidMount(){
console.log('component is mounted');
}
render () {
return (
<div>
{this.props.children}
</div>
)
}
}
export default CustomComponent
Now create MyComponent.js that extends CustomComponent.js
import React, { Component } from 'react'
import CustomComponent from './CustomComponent'
class MyComponent extends CustomComponent {
render () {
return (
<div>
Hello from MyComponent
</div>
)
}
}
export default MyComponent;
now you see console , you have log : "component is mounted"
but if you write componentDidMonunt() inside MyComponent.js , you will get log from MyComponent.js

ipcRenderer in React component constructor

I have an app using Electron, React, and React Router. I'm using ipcRenderer in the component constructor to send events from my component to the main Electron process. After I added React Router to the mix, I noticed that my ipcRenderer event was getting added again and again each time I left and came back to the component. I figure it's because React Router is mounting and unmounting the component as needed.
I found a way around the issue by checking if the event already has been registered like this:
if (!ipcRenderer._events['open-file-reply']) {
ipcRenderer.on('open-file-reply', (event, fileContents) => {
if(fileContents){
this.setState({
data: JSON.parse(fileContents)
});
}
});
}
I'm just wondering if there is a more correct way to do this. Does ipcRenderer.on belong in the constructor anyway, or is there a more appropriate place to put it?
EDIT
This is the best solution I've come up with so far:
import {ipcRenderer} from 'electron';
/* inside React component */
constructor(props) {
super(props);
// ...
this.loadFileListener = this.loadFileListener.bind(this);
ipcRenderer.on('open-file-reply', this.loadFileListener);
}
componentWillUnmount() {
ipcRenderer.removeAllListeners(['open-file-reply']);
}
loadFileListener(event, fileContents) {
// set state and stuff...
}
I don't think you should be setting up IPC until the component is mounted, so I would suggest this approach:
constructor(props) {
super(props)
this._loadFileListener = this._loadFileListener.bind(this)
}
componentDidMount() {
ipcRenderer.on('open-file-reply', this._loadFileListener)
}
componentWillUnmount() {
ipcRenderer.removeListener('open-file-reply', this._loadFileListener)
}

reactjs: how to define componentDidMount inside ES6 const?

I have this react component that is not an ES6 class. It's a const like :
import React from 'react';
import Dashboard from './components/Dashboard';
const Home = (props) => {
const componentDidMount = () => {
console.log('component mounted'); // not working
}
return <Dashboard />;
}
Inside this const how do i define the componentDidMount function like i would do in a normal ES6 class? this is how i did it before.
import React from 'react';
import Dashboard from './components/Dashboard';
class Dashboard extends React.Component {
componentDidMount() {
console.log('component mounted');
}
render() {
return <Dashboard />;
}
}
Stateless functional components don't support the lifecycle methods.
You can either convert it to a stateful component or wrap it in a stateful container.
Good example of wrapping to get the lifecycle methods:
https://egghead.io/lessons/javascript-redux-fetching-data-on-route-change
To anyone else learning React and stumbling upon this in the future like me, the accepted answer here is out of date. Please see this question: componentDidMount equivalent on a React function/Hooks component?
If using React 16.8.0+ you can create the effect of componentDidMount by using the hook useEffect:
useEffect(() => {
// Your code here
}, []);

Resources