Reputation: 11
I met this problem, I need to pass to the component HeaderCommon props isMain . How should I write this? In addition, it displays an unpleasant error.
import React, { Component } from 'react';
import Index from './index/Layout/Layout';
import Gallery from './gallery/Layout/Layout';
import HeaderCommon from './Common/Header/Header';
import FooterCommon from './Common/Footer/Footer';
import { Route } from 'react-router-dom';
class Path extends Component {
state = {
isMain: null
};
render() {
if (window.location.pathname === '/') {
this.setState({ isMain: true });
} else if (window.location.pathname === '/ourworks') {
this.setState({ isMain: false });
}
return (
<div>
<HeaderCommon isMain={this.state.isMain} />
<Route path='/' exact component={Index} />
<Route path='/ourworks' exact component={Gallery} />
<FooterCommon />
</div>
);
}
}
export default Path;
Error: Maximum update depth exceeded. This can happen when a component repeatedly calls setState inside componentWillUpdate or componentDidUpdate. React limits the number of nested updates to prevent infinite loops.
Upvotes: 1
Views: 49
Reputation: 1923
A react hookful solution
An alternative to the class-based solution is involving React's new addition of hooks.
React hooks were introduced in React v16.8 and highly reduce the boilerplate your code requires to initialize and render components.
If you're interested I highly recommend exploring the React hook documentation here.
import React, { Component, useState, useEffect } from "react";
import Index from './index/Layout/Layout';
import Gallery from './gallery/Layout/Layout';
import HeaderCommon from './Common/Header/Header';
import FooterCommon from './Common/Footer/Footer';
import { Route } from 'react-router-dom';
export const Path = (props) => {
const [isMain, setIsMain] = useState(null);
useEffect(() => {
setIsMain(window.location.pathname === '/')
}, []);
return (
<div>
<HeaderCommon isMain={isMain} />
<Route path='/' exact component={Index} />
<Route path='/ourworks' exact component={Gallery} />
<FooterCommon />
</div>
);
};
The useState hook is common-place in React functional components and is imported directly from react with import {useState} from "react
.
We simply provide a default value in the function expression, E.G. useState(null)
which will set out initial state to a value of null. We can set this value to be any value, a data structure or an object.
We assign a way to access and set the state with array destructuring:
const [isMain, setIsMain] = useState(null);
We can now access our state with calls to isMain or set the state with setIsMain.
The useEffect hook is similar to componentDidMount
and componentDidUpdate
lifecycle methods in class-based React. This hook will automatically call depending on the second argument you pass to this hook. If no second argument is supplied, the hook will automatically act as componentDidUpdate
.
In the solution above, I pass an empty array ([]) as a second parameter to the useEffect hook callback. This means that the state value only updates on the components initial render and is effectively equivalent to componentDidMount
.
useEffect(() => {
setIsMain(window.location.pathname === '/')
}, []);
Additonally, we can pass values into this array to tell React when the component should re-render, but that's outside the scope of this answer.
Again, much more details about the useState hook, useEffect hook, and React hooks in general can be found in the docs.
Upvotes: 3
Reputation: 15166
You are causing continuous renders by modifying the state in the render()
function.
Instead I would do the following - not using for isMain
state variable:
render() {
let isMain = false;
if (window.location.pathname === '/') {
isMain = true;
} else if (window.location.pathname === '/ourworks') {
isMain = false;
}
return (
<div>
<HeaderCommon isMain={isMain} />
<Route path='/' exact component={Index} />
<Route path='/ourworks' exact component={Gallery} />
<FooterCommon />
</div>
);
}
Or even shorter:
render() {
const isMain = window.location.pathname === '/';
return <div>
<HeaderCommon isMain={isMain} />
<Route path='/' exact component={Index} />
<Route path='/ourworks' exact component={Gallery} />
<FooterCommon />
</div>
}
I hope this helps!
Upvotes: 2