i have a component names "Home" and i have a useEffect inside it which has a console.log("Home component mounted"). I just used a common useEffect hook. But when i initially render the page I getting the console log 2 times instead of showing it in the initial mounting of component. Can anyone tell me whats happening with my code. The code is as follows:
import React, { useEffect } from 'react';
const Home = () => {
useEffect(()=>{
console.log("Home component mounted")
})
return (
<div className="container">
<h1 className="h1">Home Page</h1>
</div>
)};
export default Home;
It's happening because in your app in strict mode. Go to index.js and comment strict mode tag. You will find a single render.
This happens is an intentional feature of the React.StrictMode. It only happens in development mode and should help to find accidental side effects in the render phase.
Or you can try to use this hook : useLayoutEffect
import React, { useLayoutEffect } from "react";
const Home = () => {
useLayoutEffect(() => {
console.log("Home component mounted");
}, []);
return (
<div className="container">
<h1 className="h1">Home Page</h1>
</div>
);
};
export default Home;
It is because of React.StrictMode
You don't have to worry- just that StrictMode runs your effect code twice(only during development, don't have to worry about production) to be able to catch bugs and memory leaks among other things
Read more: https://reactjs.org/docs/strict-mode.html
Screenshot here
useEffect() equivalent with componentDidMount() and componentDidUpdate(). This means when rendering your component, useEffect() will be called twice. If you want useEffect() only called one time, you just add the second parameter for it. It will as this.
useEffect(()=>{
console.log("Home component mounted")},[])
I hope this helpful for you!
Related
I have developed my own website and have errors using react hook.
The errors are like below.
Uncaught Error: Invalid hook call. Hooks can only be called inside of
the body of a function component. This could happen for one of the
following reasons:
You might have mismatching versions of React and the renderer (such as React DOM)
You might be breaking the Rules of Hooks
You might have more than one copy of React in the same app
And here is my code:
import React from 'react';
import { useSelector } from 'react-redux';
import 'bootstrap/dist/css/bootstrap.min.css';
const ProfileEditing = ({
}) => {
const user = useSelector(state => state.auth);
console.log(user);
return (
<section className="dashboard">
<div className='side'>
<h1 className="large text-primary">Dashboard</h1>
<p className="lead">
</div>
</section>
);
};
export default ProfileEditing;
I try to fix it but doesn't work at all.
Please help me.
I fixed error.
The problem is not because of code but because of node_modules.
I removed package-lock.json and node_modules and reinstall it.
And it works now.
I'm currently building a website where I need to build a carousel. The carousel needs to have a 'progress bar' as the indicator for the current slide (like here: https://www.samsung.com/uk).
I'm familiar with react-responsive-carousel, but it doesn't have the functionality built in for the progress bar.
I've used state to effectively build a stopwatch to facilitate the progress bar inside my component.
Instead of using the built in autoplay functionality from react-responsive-carousel, I'd like to have a function that is triggered once the interval is finished to move on to the next slide.
The problem I'm having is, I'm not sure how to trigger this action. I've checked the docs, and it looks like I need to trigger onClickNext (see here, line 528), but I can't figure out how to do that.
I'm currently using a functional component, rather than a class based component, if that makes a difference. I just need to understand how I can trigger that action from my component.
Thanks
Maybe triggering the function inside of that class component using a ref is the way.
It seems to be the solution you're looking for.
import { Carousel } from "react-responsive-carousel";
import "react-responsive-carousel/lib/styles/carousel.min.css";
import { useEffect, useRef } from "react";
const App = () => {
const myRef = useRef();
useEffect(() => {
setTimeout(() => {
if (myRef) myRef.current.onClickNext();
}, 2000);
}, []);
return (
<Carousel ref={myRef}>
<div>
<p>Slide 1</p>
</div>
<div>
<p>Slide 2</p>
</div>
</Carousel>
);
};
export default App;
Code Sandbox
import React, { useState, useEffect } from "react";
const Foo = () => {
console.log("render foo");
return <div> foo</div>;
};
const App = () => {
const [value, setValue] = useState(1);
useEffect(() => {
console.log("effect", value);
}, [value]);
console.log("rendering");
return (
<div>
{" "}
<Foo /> <button onClick={() => setValue(value)}>Click To Render</button>
</div>
);
};
export default App;
Now according to the React Documentation
If you update a State Hook to the same value as the current state, React will bail out without rendering the children or firing effects. (emphasis mine)
(React uses the Object.is comparison algorithm.)
Note that React may still need to render that specific component again before bailing out. That shouldn’t be a concern because React won’t unnecessarily go “deeper” into the tree. If you’re doing expensive calculations while rendering, you can optimize them with useMemo.
In the example I've given, we can see that the useEffect hook doesn't fire, as described by the documentation, but my Foo component is rendering.
Why is this?
I thought that maybe the inline function causes a render - but if I change that to a memoized function using useCallback the same behaviour happens:
const handleClick = useCallback(() => setValue(value), [value]);
console.log("rendering");
return (
<div>
{" "}
<Foo /> <button onClick={handleClick}>Click To Render</button>
</div>
The bail out logic was implemented in v16.8.0 of react-dom in which react also introduced hooks, whereas your demo uses the alpha version of hooks which is why you still see a re-render being triggered even when you update with the same state
According to v16.8.0 release notes
Bail out of rendering on identical values for useState and useReducer Hooks. (#acdlite in #14569)
I'm confused as to why nothing happens when I'm clicking links in my app.
In my index.js file, I am loading my main screen called 'Game'. Inside 'Game', I have two links, that when clicked, should render another screen.
In my index.js:
import React from "react";
import ReactDOM from "react-dom";
import Game from "./Game/Game";
ReactDOM.render(
<React.Fragment>
<Game/>
</React.Fragment>,
document.getElementById('gameContainer')
)
In my index.html:
<div>
<div id="gameContainer"></div>
</div>
<div id="root"></div>
My Game.js:
import React from "react";
import CharacterStats from "../CharacterStats";
import DungeonStats from "../DungeonStats";
const characterStatsComponent = () => {
return (
<CharacterStats />
);
}
const dungeonStatsComponent = () => {
return (
<DungeonStats />
);
}
const Game = () => (
<div>
<a id="showCharacter" href="#" onClick={characterStatsComponent}>Show your character</a>
</div>
<br />
<div>
<a id="showDungeon" href="#" onClick={dungeonStatsComponent}>Show current dungeon</a>
</div>
);
export default Game;
The two other components, CharacterStats and DungeonStats are just a few bits of html and reactjs to show some data.
Neither CharacterStats or DungeonStats are loading when I'm clicking the links.
I am also getting no errors in the console.
Nothing happens when the links are clicked.
I also put this inside each onClick event:
console.log('link was clicked');
And it does show the message in the console. So that shows that it knows the link is being clicked.
Is there anything that would prevent them from being loaded?
Thanks!
It wont work because you are returning jsx into the onClick function context, and not into the Game component's return value.
You could define a state using useState, something like showDungeon and showCharacter that defaults to false, change it to true onClick, and in the Game component's return value add:
{ showDungeon && <DungeonStats /> }
React uses something called Synthetic Events to achieve cross browser event handling. If I understood your question correctly than changing the onclick to onClick should do the job for you.
Below you can see simpliest component ever that renders a functional component using hooks.
import React, { Component, useState } from 'react'
export default class ImageList extends Component {
render() {
return (
<div>
{RenderImages()}
</div>
)
}
}
export const RenderImages = (props) =>
{
const [images,setImages] = useState([])
return(
<div>
Images will be rendered here!
</div>
)
}
Searched but couldn't find solution... Why it's not working? what is wrong with hooks here?
<div>
{RenderImages()}
</div>
As you have called RenderImages as a function and it's confused as there is a Hook usage. If you used it like this it'll work as use it includes RenderImages as a Functional Component.
<div>
<RenderImages />
</div>
https://reactjs.org/docs/hooks-rules.html
Don’t call Hooks inside loops, conditions, or nested functions. Instead, always use Hooks at the top level of your React function.