I'm using a template for my React app, and I came across one component that constantly gives me the following warning:
Warning: componentWillMount has been renamed, and is not recommended for use. See https:... for details.
Now, I'm trying to rewrite this component to React Hooks, to avoid multiple warnings in the console.
This is how the component looks like:
import React, { Component } from 'react';
import Nprogress from 'nprogress';
import ReactPlaceholder from 'react-placeholder';
import 'nprogress/nprogress.css';
import 'react-placeholder/lib/reactPlaceholder.css';
import CircularProgress from '../components/CircularProgress/index';
export default function asyncComponent(importComponent) {
class AsyncFunc extends Component {
constructor(props) {
super(props);
this.state = {
component: null,
};
}
componentWillMount() {
Nprogress.start();
}
componentWillUnmount() {
this.mounted = false;
}
async componentDidMount() {
this.mounted = true;
const { default: Component } = await importComponent();
Nprogress.done();
if (this.mounted) {
this.setState({
component: <Component {...this.props} />,
});
}
}
render() {
const Component = this.state.component
|| (
<div
className="loader-view"
style={{ height: 'calc(100vh - 200px)' }}
>
<CircularProgress />
</div>
);
return (
<ReactPlaceholder type="text" rows={7} ready={Component !== null}>
{Component}
</ReactPlaceholder>
);
}
}
return AsyncFunc;
}
And here is the example of its usage:
import React from 'react';
import { Route, Switch, withRouter } from 'react-router-dom';
import asyncComponent from '../util/asyncComponent';
const Routes = ({ match }) => (
<Switch>
<Route
path={`${match.url}/main`}
component={asyncComponent(() => import('./routes/MainPage/index'))}
/>
{/* <Route component={asyncComponent(() => import("app/routes/extraPages/routes/404"))}/> */}
</Switch>
);
export default withRouter(Routes);
I know how to rewrite component lifecycle methods ( componentDidMount
, componentWillUnmount
should be rewritten to useEffect
), but I don't understand part with props
- asyncComponent
gets importComponent
as a prop, but where are we getting props
in AsyncFunc? And how this could be rewritten to the functional component?
As I understood, asyncComponent
is a Higher Order Component that responds with an updated component.
Sorry for not providing a sandbox for this example.
I couldn't test this code but I think is a solution
import React, { useState, useEffect } from 'react';
import Nprogress from 'nprogress';
import ReactPlaceholder from 'react-placeholder';
import 'nprogress/nprogress.css';
import 'react-placeholder/lib/reactPlaceholder.css';
import CircularProgress from '../components/CircularProgress/index';
const asyncComponent = importComponent => {
const [component, setComponent] = useState(null);
Nprogress.start();
useEffect(async () => {
const { default: Component } = await importComponent();
Nprogress.done();
setComponent(<Component {...importComponent} />);
}, []);
return component ? (
<ReactPlaceholder type="text" rows={7} ready>
{component}
</ReactPlaceholder>
) : (
<div className="loader-view" style={{ height: 'calc(100vh - 200px)' }}>
<CircularProgress />
</div>
);
};
export default asyncComponent;
I don't see the need to use the state mounted because you only use it in the dismount to setState component, but if 2 lines before you set mounted as true, it is not necessary to generate a re-render, you can go and setState component directly.
I hope this helps you.
According to reactjs.org, componentWillMount will not be supported in the future. https://reactjs.org/docs/react-component.html#unsafe_componentwillmount
There is no need to use componentWillMount.
Before discussing your question but where are we getting props in AsyncFunc?
start with an example
const A = props => {
return <p>{JSON.stringify(props.location)}</p>;
};
function App() {
return (
<Switch>
<Route exact path="/" component={A} />
<Route exact path="/a" component={p => <A {...p} />} />
</Switch>
);
}
/
and route /a
both components are getting props but in different ways /
the props are automatically passed to the component As you know HOC
take a component and in response, it returns a component
so asyncComponent(() => import('./routes/MainPage/index')
will return AsyncFunc
so we can simply say that
<Route
path={`${match.url}/main`}
component={AsyncFunc}
/>
and that's all
component={AsyncFunc} is equal to component={(p) => <AsyncFunc {...p} />}
and that how pros are passing
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.