Component showing and triggers onclick - reactjs

Hi I have this component named "ConfirmSave". I have certain condition before I show this component
{FormStatus.statusMode === "Success" && (
<ConfirmSave FormStatus={FormStatus} />
)}
Inside this component I have this
const ConfirmSave = () => {
return ( <div className="col">
<a
className="btn confirm-btn yes-sign col"
onClick={console.log("TEST")} ) > test</a></div>
}
My problem is, even the link is not yet click the "onClick" its activating, it saying TEST in my log

Oh i am calling the function not the trigger
() => { this.props.removeTaskFunction(todo)

Related

How to fix this error in react `onClick` listener to be a function, instead got a value of `string` type

I have this codes in react:
const [categoryId, setCategoryId] = useState("");
{
catName.map((singleCategory, index) => {
const { catName, _id: categoryId } = singleCategory;
return (
<>
<div
className="category-single-div flex-3 center-flex-align-display"
key={index}
>
<p className="text-general-small2 category-custom-text">{catName}</p>
<div className="category-icons-div ">
<FaEdit
className="category-icon-edit"
onClick={() => {
setEditCategory(true);
setCategoryId(categoryId);
}}
/>
<AiFillDelete className="category-icon-edit category-icon-delete" />
</div>
</div>
</>
);
});
}
I used map to get an array of objects, and I needed their individual _id when a user clicks the edit button. I also want to call another function on the same edit button via onClick. It is working but displays an error.
Warning: Expected onClick listener to be a function, instead got a
value of string type.
I need that _id so as to pass it to a state and have access to it globally within the component at the top level.
Is this workable?
Your problem comes from the FaEdit component.
<FaEdit
id={categoryId}
className="category-icon-edit"
onClick={(editCategory, id) => { // you need to have onClick as a prop defined inside the FaEdit component
setEditCategory(editCategory);
setCategoryId(id);
}}
/>
Example...
export default function FaEdit({className, onClick, categoryId}){
const handleChange() => {
onClick(true, categoryId)
}
return(
<div className={className} onClick={() => handleChange()}>Click</div>
)
}

Render JSX from material-ui Button onClick

I'm trying to render JSX when a material-ui button is clicked. I'm logging to the console when clicking but cannot see any of the JSX getting rendered.
interface TileProps {
address?: string;
}
const renderDisplayer = (address: string) => {
console.log('Rendering address', address!);
if (typeof(address) == 'undefined' || address == '') {
return(<div className='error'><li>No address found</li></div>)
}
return(<AddressDisplayer address={address} />)
}
const Tile = (props: TileProps) => {
return(
<div className='tile'>
<ul>
<li>{props.address}</li>
</ul>
<Button variant='contained' onClick={() => {renderDisplayer(props.address)}}>Display</Button>
</div>
)
}
export default Tile;
I can see the console.log('Rendering address', address!); running when the button is clicked, but the JSX isn't getting rendered.
Could this be because I'm using React functional components instead of class components?
Your question is somehow unclear for me. If you want to render <div className='error'><li>No address found</li></div> based on typeof(address) == 'undefined' || address == '' condition, there is no need to click on the button and it's better to use conditional rendering. For example:
{!props.address ? (
<div className='error'><li>No address found</li></div>
) : (
<AddressDisplayer address={props.address} />
)}
But if you want to render your address component by clicking on the button, you should define a state and set it true when clicking on the button. Like this:
const [shouldShowAddress, setShouldShowAddress] = useState(false);
{shouldShowAddress && (
<>
{!props.address ? (
<div className="error">
<li>No address found</li>
</div>
) : (
<AddressDisplayer address={props.address} />
)}
</>
)}
<Button
variant="contained"
onClick={() => {
setShouldShowAddress(true)
}}
>
Display
</Button>
Please read about the Life cycle This not how react work onclick function
renderDisplayer is called and return JSX to onClick event you need to use state here to render the component with ternary oprator renderDisplayer fuction do setState so DOM will update

state is not updating when the component re renders?

I'm making a Nextjs flashcard app. I'm passing a deck structure like this:
const deck = {
title: 'React 101',
flashcards: [flashcardOne, flashcardTwo],
};
as props to the Deck component. This component shows the first card in flashcards and a "next" button to increment the index and showing the next card in flashcards.
The Card component is very simple and shows the front and the back of the card depending of the state front.
This is what I got so far and it's working but if I click "next" when the card is showing the answer (flashcard.back), the next card is going to appear with the answer. And I'm not sure why, isn't the Card component re rendering when I click "next"? And if the component re renders, front is going to be set to true?
export default function Deck({ deck }) {
const [cardIndex, setCardIndex] = useState(0);
const { title, flashcards } = deck;
return (
<div className={styles.container}>
<main className={styles.main}>
<h1 className={styles.title}>{title}</h1>
{cardIndex < flashcards.length ? (
<>
<div className={styles.grid}>
<Card flashcard={flashcards[cardIndex]} />
</div>
<button onClick={() => setCardIndex((cardIndex) => cardIndex + 1)}>
Next
</button>
</>
) : (
<>
<div>End</div>
<button>
<Link href='/'>
<a>Go to Home</a>
</Link>
</button>
<button onClick={() => setCardIndex(0)}>Play again</button>
</>
)}
</main>
</div>
);
}
export function Card({ flashcard }) {
const [front, setFront] = useState(true);
return (
<>
{front ? (
<div
className={`${globalStyles.card} ${styles.card}`}
onClick={() => setFront(false)}
>
<p className={styles.front}>{flashcard.front}</p>
</div>
) : (
<div
className={`${globalStyles.card} ${styles.card}`}
onClick={() => setFront(true)}
>
<p className={styles.back}>{flashcard.back}</p>
</div>
)}
</>
);
}
When state changes, the card will re-render, but it will not re-mount. So, existing state will not be reset.
Call setFront(true) when the flashcard prop has changed:
const [front, setFront] = useState(true);
useLayoutEffect(() => {
setFront(true);
}, [flashcard]);
I'm using useLayoutEffect instead of useEffect to ensure front gets set ASAP, rather than after a paint cycle (which could cause flickering).
You can also significantly slim down the Card JSX:
export function Card({ flashcard }) {
const [front, setFront] = useState(true);
const face = front ? 'front' : 'back';
return (
<div
className={`${globalStyles.card} ${styles.card}`}
onClick={() => setFront(!front)}
>
<p className={styles[face]}>{flashcard[face]}</p>
</div>
);
}
Okay, I guess I had the same issue. Since you're using functional components, and you're re-using the same component or in better words, you're not unmounting and remounting the component really, you're just changing the props, this happens. For this, you need to do useEffect() and then setFront(true).
Here's the code I used in my App.
useEffect(() => {
setFront(true);
}, [flashcard]);
This is what I have used in my Word.js file.

"Error: Too many re-renders. React limits the number of renders to prevent an infinite loop."

Hi I have been stuck in a React Function useState. I just want to learn hooks and useState, but I can not have any progress even struggling too much to find a solution. Here is my full react function:
import React, { useState } from 'react';
import './MainPart.css';
function MainPart(props) {
const [orderData_, setOrderData_] = useState(props.orderData);
let topicData_ = props.topicData;
let titleData_ = props.titleData;
let infoData_ = props.infoData;
return (
<div className='MainPart'>
<div className='mainWindow'>{getPics(orderData_)}</div>
<div className='information'>
<div className='moreNewsDivs'>
<div className='moreNewsDiv1'>
<h4>MORE NEWS</h4>
</div>
<div className='moreNewsDiv2'>
<button
className='previous-round'
onClick={setOrderData_(previous(orderData_))}
>
‹
</button>
<button href='/#' className='next-round'>
›
</button>
</div>
</div>
<hr />
<div className='topicDiv'>
<h5 className='topicData'>{topicData_}</h5>
<h5 className='titleData'>{titleData_}</h5>
<h6 className='infoData'>{infoData_}</h6>
</div>
</div>
</div>
);
}
function previous(orderData_) {
let newOrderData;
if (orderData_ === 3) {
newOrderData = 2;
console.log(newOrderData);
return newOrderData;
} else if (orderData_ === 1) {
newOrderData = 3;
console.log(newOrderData);
return newOrderData;
} else {
newOrderData = 1;
console.log(newOrderData);
return newOrderData;
}
}
function next(orderData_) {
let newOrderData;
if (orderData_ === 3) {
newOrderData = 1;
} else if (orderData_ === 2) {
newOrderData = 3;
} else {
newOrderData = 2;
}
return newOrderData;
}
const getPics = picOrder => {
if (picOrder === 1) {
return (
<img
src={require('../assets/desktopLarge/mainImage.png')}
className='MainImage'
alt=''
id='mainImage'
/>
);
} else if (picOrder === 2) {
return (
<img
src={require('../assets/desktopLarge/bridge.png')}
className='MainImage'
alt=''
id='mainImage'
/>
);
} else {
return (
<img
src={require('../assets/desktopLarge/forest.png')}
className='MainImage'
alt=''
id='mainImage'
/>
);
}
};
export default MainPart;
I am getting an error while using useState. Even loading the page fresh and not pressed to anything my buttons onClick event listener activated and As I mentioned before at the topic My Error:
"Error: Too many re-renders. React limits the number of renders to
prevent an infinite loop."
The problem can be found in your onClick prop:
<button className="previous-round" onClick={setOrderData_(previous(orderData_))}>‹</button>
^
Everything between the curly braces gets evaluated immediately. This causes the setOrderData_ function to be called in every render loop.
By wrapping the function with an arrow function, the evaluated code will result in a function that can be called whenever the user clicks on the button.
<button className="previous-round" onClick={() => setOrderData_(previous(orderData_))}
>‹</button>
You can find more information about JSX and expressions in the official docs
https://reactjs.org/docs/introducing-jsx.html#embedding-expressions-in-jsx
Infinite re-render loop
The reason for the infinite loop is because something (most likely setState) in the event callback is triggering a re-render. This will call the event callback again and causes React to stop and throw the 'Too many re-renders.' error.
Technical explanation
To better understand the reason why JSX works this way see the code below. JSX is actually being compiled to Javascript and every prop will be passed to a function in an Object. With this knowledge, you will see that handleEvent() is being called immediately in the last example.
// Simple example
// JSX: <button>click me</button>
// JS: createElement('button', { children: 'click me' })
createElement("button", { children: "click me" });
// Correct event callback
// JSX: <button onClick={handleClick}>click me</button>
// JS: createElement('button', { onClick: handleClick, children: 'click me' })
createElement("button", { onClick: handleClick, children: "click me" });
// Wrong event callback
// JSX: <button onClick={handleClick()}>click me</button>
// JS: createElement('button', { onClick: handleClick(), children: 'click me' })
createElement("button", { onClick: handleClick(), children: "click me" });
Just replace your button with the one below
<button className="previous-round" onClick={() => setOrderData_(previous(orderData_))}>‹</button>
This happens because onClick function if used without an anonymous functions gets called immediately and that setOrderData again re renders it causing an infinite loop. So its better to use anonymous functions.
Hope it helps. feel free for doubts.
When I go through your code, I found something.
Onclick function needs to be arrow function. Onclick is an event and you are just calling a function inside onclick directly. This leads to too many re-renders because you are setting state directly inside the return. That does not work.
Calling setState here makes your component a contender for producing infinite loops. render should remain pure and be used to conditionally switch between JSX fragments/child components based on state or props. Callbacks in render can be used to update state and then re-render based on the change
This above line taken from link here: https://itnext.io/react-setstate-usage-and-gotchas-ac10b4e03d60
Just use Arrow (=>) function:
<button className="previous-round" onClick={() => setOrderData_(previous(orderData_))}>
‹
</button>
use
<button
className='previous-round'
onClick={() => setOrderData_(previous(orderData_))}
>
‹
</button>
This worked for me...

React - onClick event not working correctly

I'm attempting to pass an onClick function as a prop to a child component in React. However, nothing is being logged to the console when the button is clicked. For now I'm just trying to console log to make sure the event is actually firing.
Any Ideas?
class App extends React.Component {
togglePallets = (pallet) => {
console.log('test');
}
render() {
return (
<div className="mainWrapper">
<div className="mainContainer">
<div>
<img src="images/picture-of-me.jpg" alt="Me"></img>
</div>
</div>
<SideBar toggle={this.togglePallets} showPallets={[this.state.showAboutPallet, this.state.showLanguagesPallet,
this.state.showProjectsPallet, this.state.showContactPallet]}/>
{this.state.showAboutPallet && <AboutPallet />}
{this.state.showAboutPallet && <LanguagesPallet />}
{this.state.showAboutPallet && <ProjectsPallet />}
{this.state.showAboutPallet && <ContactPallet />}
</div>
);
}
}
function SideBar(props) {
return (
<div className="sideBarContainer">
<Button icon={faUser} showAboutPallet={props.showPallets[0]} onClick={props.toggle}/>
</div>
);
}
What you have written is correct. But we can try it in another way using an arrow function.
onClick={(e) => props.toggle(e,data)}
And, make relevant changes in toggle function, so it may support multiple arguments.
Change your togglePallets to any of the below
togglePallets() {
console.log("test");
};
If you want to access event then
togglePallets(event) {
console.log("test");
};
Or
togglePallets=event =>{
console.log("teeventst");
};

Resources