I found this error :
Can't call setState (or forceUpdate) on an unmounted component. This is a no-op, but it indicates a memory leak in your application. To fix, cancel all subscriptions and asynchronous tasks in the componentWillUnmount method.
Context : When I'm connected, I'm on the homepage, this page not contain the breadCrumb, but If I go on CampaignPage
(also the name of the component), I have the BreadCrumb
(Component name) I found this error.
On other post what I could see, they said probably problem on asynchronously on ComponentWillMount
but I think my problem is different and I can't find a solution.
My code look like that :
import React, { Component } from 'react';
import PropTypes from 'prop-types';
import { connect } from 'react-redux';
import classnames from 'classnames';
import objectAssign from 'object-assign';
import { withRouter } from 'react-router';
import {
BREADCRUMBS_ROUTES,
BREADCRUMBS_ROUTES_FOR_ID,
BREADCRUMBS_ENDPOINT
} from 'constants';
import { getEntityById, setUpdatedBreadcrumbs } from 'actions/breadcrumbs';
import style from './style.scss';
class Breadcrumbs extends Component {
constructor(props) {
super(props);
this.state = {
breadcrumbs: [],
names: {}
};
this.setBreadcrumbs = this.setBreadcrumbs.bind(this);
this.loadEntityNameById = this.loadEntityNameById.bind(this);
}
componentWillMount() {
this.setBreadcrumbs();
}
componentWillReceiveProps(nextProps) {
const { isWillUpdate: newIsWillUpdate } = nextProps;
const { isWillUpdate, saveUpdatedBreadcrumbs } = this.props;
if (isWillUpdate === false && newIsWillUpdate === true) {
this.setBreadcrumbs();
saveUpdatedBreadcrumbs();
}
}
setBreadcrumbs() {
const { params, path } = this.props.match;
let currentPath = '';
const pathSplitedAndExtendet = path.split('/')
.filter(item => !!item)
.map(item => {
if (item[0] === ':' && item.slice(1) !== 'adPage') {
const parameterName = item.slice(1);
this.loadEntityNameById(
parameterName,
params[parameterName]
);
return {
route: `/${params[parameterName]}${BREADCRUMBS_ROUTES_FOR_ID[parameterName]}`,
parameter: parameterName
};
}
return {
route: `/${item}`,
parameter: ''
};
});
const breadcrumbs = pathSplitedAndExtendet
.filter(item => item.parameter !== 'adPage')
.map((item) => {
const indexOfRoute = currentPath.indexOf(item.route);
if (currentPath.slice(indexOfRoute) !== item.route) {
currentPath = `${currentPath}${item.route}`;
}
return ({
...item,
name: BREADCRUMBS_ROUTES[item.route] || '',
route: currentPath
});
});
this.setState({ breadcrumbs });
}
async loadEntityNameById(parameter, id) {
const { loadEntityById } = this.props;
await loadEntityById(BREADCRUMBS_ENDPOINT[parameter], id)
.then((data) => {
this.setState({ names: objectAssign(this.state.names, { [parameter]: { id, name: data.name } }) });
});
}
render() {
const { breadcrumbs, names } = this.state;
const { showBreadcrumbs } = this.props;
return (
<div className={style.breadcrumbs}>
{
showBreadcrumbs && breadcrumbs
.map((item, index) => {
return (
<div
key={`${item.name}--${item.route}--${index}`}
className={classnames(style.bread, index === breadcrumbs.length - 1 ? style.last : null)}
role="link"
tabIndex={-10 - index}
onKeyDown={() => {}}
onClick={item.route ? () => this.props.history.push(item.route) : null}
>
{`${item.name || (names[item.parameter]
? names[item.parameter].name : '...')}
${((breadcrumbs.length > 1) && (index !== breadcrumbs.length - 1)) ? ' >' : ''}
`}
</div>
);
})
}
</div>
);
}
}
export default connect(mapStateToProps, mapDispatchToProps)(withRouter(Breadcrumbs));