in react I am displaying products I.E.
{renderPosts.map((item, index) => (
...
now, in each product, there is a button to delete that product, inside a button I have onclick that calls sweetAlert to delete particular product:
<Button
color="danger"
simple
justIcon
onClick={warningWithConfirmMessage}
>
Everything works fine like that... but if I want to pass ID of the product that has to be deleted...
<Button
color="danger"
simple
justIcon
onClick={warningWithConfirmMessage(item.postId)}
>
Now I am having error:
Too many re-renders. React limits the number of renders to prevent an infinite loop.
How I can pass anything to function... anybody
Thanks in advance!
The new onClick handler you're passing is calling the warningWithConfirmMessage every time it renders. To pass the function as a handler function instead of calling it, use:
onClick={() => warningWithConfirmMessage(item.postId)}
Related
This question already has answers here:
What is the difference between a function call and function reference?
(6 answers)
Closed 2 years ago.
I am new to react and learning it via reactjs.org "Tic Tac Toe" tutorial, i have question on below.
function Square(props){
return(
<button className="square"
onClick={() => props.onClick()}>
{props.value}
</button>
);
}
Can be written as
function Square(props){
return(
<button className="square"
onClick={props.onClick}>
{props.value}
</button>
);
}
However below is incorrect
function Square(props){
return(
<button className="square"
onClick={props.onClick()}>
{props.value}
</button>
);
}
Can someone explain why "onClick={props.onClick()}" is incorrect however both "onClick={() => props.onClick()}" and
"onClick={props.onClick}" are correct.?
When using "onClick={props.onClick()}" it compiles fine however react throws below error at run time.
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.
onClick={props.onClick()}
This one means "immediately call props.onClick(), and pass it's result into the onClick prop". Assuming props.onClick returns undefined, you're passing undefined into the click handler, so nothing will happen when it's clicked.
onClick={() => props.onClick()}
This means "create a function with the text () => props.onClick() and pass it into the onClick prop". Later, when a click happens, the function will be run, which in turn will run props.onClick.
onClick={props.onClick}
This means "pass props.onClick into the onClick prop". Later, when a click happens, props.onClick will be run.
onClick={props.onClick()} is executing when the component is rendered.
onClick={() => props.onClick()} will be executed when the user click, but can be passed params directly, like this: onClick={() => props.onClick(this, id)}
onClick={props.onClick} will be executed when the user click, passing the event as a param. In this approach, you are passing a reference.
Related question: What is the difference between a function call and function reference?
I am working with mapbox react gl - It is working pretty nice so far... except one thing.
The user can add their hometown location to the map. When the hometown location appears, it can be clicked to view a popup. I want the user to be able to remove the location from the map from inside the popup - So I added a function that removes the location from the database when a button is clicked. The problem is when the button is inside the popup the function doesn't fire - and I have no idea why.
I have messed with the z index of the button but it seems like whenever the button is clicked, the onClose function is being called instead of my handleDeleteHome function...
Edit* If I remove the onClose function, the handleDeleteHome function fires.
Any help is appriciated! Thanks!
{selectedHome && (
<Popup
latitude={bandLocation[0]}
longitude={bandLocation[1]}
onClose={() => {setSelectedHome(null)}}
offsetLeft={23}
offsetTop={-10}
>
<div>
<h4>Home Town</h4>
<Button
onClick={(e) => {
e.preventDefault()
handleDeleteHome()
}}
color="danger">x</Button>
</div>
</Popup>
)}
Alright! Figured it out - If anyone else needs to know:
You need to add closeOnClick={false} to the popup!
I've been using react-table heavily throughout my React app which has been so useful but now I've got a weird bug I believe
I've got a react table with a subcomponent structured as such
<ReactTable
data={Data}
columns={columns}
SubComponent={row => {
return (
<div>
<p>I am the subcomponent</p>
<button onClick={this.toggleHidden.bind(this)} >
Click to additional information
</button>
{!this.state.isHidden && <p>Hello world</p>}
</div>
);
}}
/>
And here's what that looks like in the browser - the blue button on the left opens and closes the subcomponent and that works just fine, I've used subcomponents like this throughout my React App with no problems
When clicking the 'Click to additional information' button I want to show additional information ('Hello world' in this example) it runs this piece of code
constructor () {
super()
this.state = {
isHidden: true
}
}
toggleHidden () {
this.setState({
isHidden: !this.state.isHidden
})
}
But what happens in the browser is that the subcomponent toggle is closed and looks like this
If I reopen the subcomponent you can see that the 'hello world' is now showing so if did work as I wanted but just automatically closing the subcomponent which I didn't want to happen
In the console I'm not getting any errors or logs from react-table - it seems that any time I try to set a state inside of the react-table subcomponent that it will automatically close like this
My guess is that setting the state has reset all the states and that is what is confusing react-table, but I don't see how it would be?
I've just updated react-table to the latest version 6.8.6 but still have the same problem
Is this a bug or is there something I've done wrong here?
i fixed this by collapseOnDataChange: false
I had a similar issue. I have a subcomponent and inside the subcomponent are buttons which trigger functions when clicked:
The delete button had the following code:
<button id="delete" onClick={this.deleteClient('id')}>Delete</button>
where deleteClient is defined as:
deleteClient = (clientRef) => {
console.log(`deleting ${clientRef}`)
}
With the above code, "deleting id" would console.log both when I opened the subcomponent and when I clicked on the button.
I resolved the problem by using a callback in onClick as such:
<button id="delete" onClick={() => this.deleteClient('id')}>Delete</button>
Now "deleting id" only console.logs once, at the appropriate time, which is when I hit "Delete".
TL;DR:
set your onClick to a callback function.
Hope that helps!
I'm fairly new to React and I'm using the Ant Design framework (https://ant.design/).
I have a table list of items that I'm looking to have a button on each so that when it is pressed additional information about that row becomes available (which is a secondary API call specific to that row).
I'm trying to use a popover but I'm noticing that the popover wants the text before being rendered which is a problem since I don't have that information until the second API call. The best idea I've come up so far is to have the button press trigger the api call and then the state is updated but that creates a funky experience (as it is update after the popover is already opened - after starting with the previous rows information). It isn't a huge amount of time but it still isn't an ideal experience.
This is what I have so far:
<Popover content={this.contentSec([record['section']])} title=
{record['section']} trigger="click">
<Button onClick={() => this.sectionAttributes(record['section'])}>
<Icon type="info-circle-o" />
</Button>
</Popover>
this.sectionAttributes triggers my fetch request. and this.contentSec does the formatting on the existing popup (see below).
contentSec(props) {
const listItems = this.state.attributes.map((item) =>
<li>{item}</li>
);
return <div><ul>{listItems}</ul></div>
}
Any ideas of a better way to handle this so that there isn't that buggy delay when clicking the button for the popover?
Thanks.
As the content is populated after the second api call, You can send two props content which can be empty string or any default value and loading variable as true on click. Once you have the data after the API call you can send the updated props ie content with actual text and loading as false and finally handle your logic and state update in componentwillrecieveprops() in the popover component.
You can use the loading prop to switch from a loader initially to the actual content.
Write a condition to check if the response from this.sectionAttributes(record['section'] is true, if it is true then
<Popover content={this.contentSec([record['section']])} title=
{record['section']} trigger="click">
<Button onClick={() => this.sectionAttributes(record['section'])}>
<Icon type="info-circle-o" />
</Button>
</Popover>
else simply use
<Button onClick={() => this.sectionAttributes(record['section'])}>
<Icon type="info-circle-o" />
</Button>
For the first time user clicks on button, the component rerenders and state gets updated, so when it rerenders you can see popover as the if condition satisfy.
https://gist.github.com/justgoof9/7610432925d5f921dc745071d1d67657
So I made the onDismiss button but when I pass it on to the onClick in the Delete button it doesn't do anything. Can anyone help me?
<IconButton aria-label="Delete" onClick={() => this.onDismiss() }>
You are creating an anonymous function that returns a onDismiss function, so when onClick is called due to a click, its only returning the function, not calling it. BTW, creating anonymous functions inside renders is frowned upon consider refactoring it out to its own function