Reputation: 338
I have a problem with componentDidMount
: everytime that i use setState
in componentDidMount
it calls render
several times in child components
, and I don't know why... look:
componentDidMount() {
const firstName = localStorage.getItem('nameLoggedUser');
const lastName = localStorage.getItem('lastNameLoggedUser');
const fullName = `${firstName} ${lastName}`.toLowerCase();
const loggedUserIs = localStorage.getItem("user-role");
const emailLoggedUser = localStorage.getItem('emailLoggedUser');
if (loggedUserIs === 'full') {
axios.get(`/api/menuDomain`)
.then(res => this.setState({
domain: res.data
}))
.catch(err => console.log(err))
}
}
But, if I use ComponentDidUpdate
, it gives:
That is correct, but the AJAX call is not happening...
I want to make the AJAX call and not have it render several times... But I don't know how... Could someone help me? Please???
And I am using react-router
too:
return (
<Router>
<Switch>
<Route path="/login" component={Login} />
<Route exact path="/" render={() =>
<Overview
{...myProps}
/>
}
/>
<Route path="/list" render={() =>
<Graphic
{...myProps}
/>
} />
</Switch>
</Router>
);
}
}
Upvotes: 1
Views: 90
Reputation: 19762
First, never wrap your routes within a stateful component. Instead, the routes should be a stateless function that just returns the same JSX route elements. For the example above, you should use a HOC
that wraps your protected routes and is only concerned with authentication: https://stackoverflow.com/a/53197429/7376526
Second, you shouldn't be storing the logged in user in plain text within local storage. Instead, it and possibly the password should be stored within a JWT token (or within some sort of hashed plus salted token) or perhaps within a secured cookie and then decoded and compared against server-side. How you're currently setting it to localStorage is incredibly insecure and anyone can simply set a user's first and last name and their "user-role" and gain access to their account.
Third, each container
should handle and fetch relevant data and pass it to a relevant component
for display. For performance, you should compartmentalize your retrieved data to relevant data for that particular component. Since you have multiple routes, fetching everything at once is wasteful. For example, fetch Overview
data inside of a FetchOverview
container's componentDidMount
, then pass it down to a DisplayOverview
child component for display. Read this for more information on containers
and components
: https://medium.com/@dan_abramov/smart-and-dumb-components-7ca2f9a7c7d0
Upvotes: 2