I have a React project where a component SubmitButton is rendered when the property isSelectedNumber change its state to true. The component SubmitButton, which is a button you can click, will call a method when the button is clicked by using the onClick function and that will lead to the property isSubmitClicked change to true that the component NextButton will render.
The thing is that just the SubmitButton is rendered and when I click the button of the component SubmitButton it doesn't render the component NextButton.
This the part of the wrapper component where both components will be rendered if the conditions are true.
{this.state.isSelectedNumber ? <SubmitButton handleClickSumbmit={this.handleClickSumbmit}/> : null}
{this.state.isSubmitClicked ? <NextButton /> : null}
This is the part of the SubmitButton Component where the onClick function should call the handleCliclkSubmit method to change the property state:
<button type="button" onClick={this.props.handleClickSubmit}></button>
This is the handleClickSubmit method:
handleClickSumbmit () {
this.setState({
isSubmitClicked: true
});
}
I was wondering if you have any idea what could be happening and how to solve it.
You have typo error
Change
<button type="button" onClick={this.props.handleClickSubmit}></button>
To
<button type="button" onClick={this.props.handleClickSumbmit}></button>
Also the function name is not meaningful in your code. Change handleClickSumbmit to handleClickSubmit wherever you have handleClickSumbmit
Also since you are using regular function you have to bind it in constructor. I hope you already did that.
I think that you should check the calling of handleClickSubmit, where you call it as handleClickSumbmit, maybe that's where the problem lies.
Related
I have a svelte app where
licking a button "Show" sets a show variable to true which shows a input text box and a save button.
Clicking the "Save" button calls a function which sets the show variable to false
Testing shows that clicking Show also triggers the on:click of Save.
Google tells me to add stopPropagation to fix this issue, but it does not fix this issue.
Any hints on what is my mistake?
A repl with my code is available at
https://svelte.dev/repl/592a544ac59a45b385ab153dec7a42f1?version=3.55.1
I forked the repl and made some changes to it
https://svelte.dev/repl/b897aa42e87d4adc8c04b381b5a66692?version=3.55.1
Here is the new code:
<script>
var name = ''
let names=[];
let show=false;
function addName(){
console.log("Clicked");
show=false;
if (name.length > 0){
names.push(name);
console.log(names)
}
}
</script>
<button on:click={()=>(show=true)} > Show
</button>
{#if show}
<input bind:value={name} type="text">
<button on:click={()=> {addName()}}>Save</button>
{/if}
<h1>Hello {name}!</h1>
You shouldn't have a propogation issue because the event listeners are not nested elements https://www.tutorialrepublic.com/javascript-tutorial/javascript-event-propagation.php
Your Save button on:click was setup like
<button on:click={addName()}>Save</button>
This definition is not correct because on:click={addName()} calls the addName function immediately. If you use this syntax you likely need to write it like this
on:click={addName}
Otherwise you can write it like your other on:click with an anonymous function (which is what I did).
on:click={()=> {addName()}}
I'm struggling with getting a modal to appear onClick(). I have a function within a component that adds players to an existing list when clicking on Add Player. The button is rendered separately in a renderAddButton() function, which passes onAddButtonClick() as a prop.
I would like for the user to be able to input the player's name in a form within a modal before it is added to the list, right now the code outputs a Player + index as the name of the player.
function onAddButtonClick() {
setItems((prev) => {
const newItems = [...prev];
newItems.push({
name: `Player ${newItems.length + 1}`,
teamId: currentTeam[0].teamId
});
playersStore.push({
name: `Player ${newItems.length + 1}`,
teamId: currentTeam[0].teamId
});
return newItems;
});
}
I have this form which I want to represent in the modal:
export const PlayerForm = () => {
return (
<div>
<form>
<input type='string' id='playerId' name='playerName' defaultValue='0' />
<input
type='number'
id='playerGoals'
name='totalGoals'
defaultValue='0'
min='1'
max='5'
/>
<input
type='number'
id='playerGoals'
name='playerGoalPercentage'
defaultValue='0'
min='1'
max='5'
/>
</form>
</div>
);
};
How do I trigger the modal from inside onAddButtonClick()?
I implement modals using the react-bootstrap framework.
From the component that I want to display the modal from, I will create a handler that will govern the component's ability to show the modal based on the bool I set in state. Typically from the parent component this show handler would look like this:
setShow = () => {
this.setState({ show: !this.state.show });
};
As seen in the example this handles a state attribute called show which is what dictates whether or not the modal gets to display in app.
Below is the implementation of the modal I would use as a child component to the parent component where it would reside and where I would pass the state attribute which I called show that dictates with true or false whether or not to display the modal:
<ExampleModal
show={this.state.show}
setShow={this.setShow}
activeRecord={this.state.activeRecord}
activePrimaryAccountId={this.state.activePrimaryAccountId}
userAccessRole={this.props.userAccessRole}
/>
I pass the necessary details that the modal needs to display as props that I get from the the parent component's state attributes. The most important being the show attributes to include the setShow function which I use in the child component (the modal itself) to update state in the parent component to close the modal when the time comes also.
In the ExampleModal component I start off with declaring state with the following attributes already loaded from props:
this.state = {
show: this.props.show,
...
}
I then use a handler that takes advantage of the setShow function passed down to the child component in props as shown:
handleClose = () => this.props.setShow(false);
In the modal component there is a button that uses this handler in its onClick() synthetic event to trigger the closing of the modal after it has rendered to the browser.
Conversely in the parent component, your button will use the onClick() synthetic event to trigger a call that would be implemented something like this in the button to open the modal:
onClick={this.setShow(true)}
I reuse that process in all of my modals in React.js, hope that helps. The trick here is using componentDidUpdate() or useEffect() (if you're using React Hooks) effectively to make sure you have the right data loaded in state in the parent component so that you can pass it into the props of the child component at the right time. The <ExampleModal /> I gave you should give you enough of a clue.
The onClick attribute for a button element created within a variable is not firing.
I tried directly defining the function in the onClick attribute, and simply out-putting to the console, but there is still nothing output to the console, and the button is not working as expected.
I also added a 'disabled={false}' attribute to the button to make sure that was not an issue, but the onClick attribute is still not working as expected.
let display = (<div className ='dtaskhome'>
<h1>Tasks</h1>
<button disabled={false} onClick={newTask} className='btask'>New Task +</button>
<ul className ='ultasks'>{taskItems}</ul>
</div>);
function newTask() {
console.log('point reached');
Tasks.props.state.newTask = true;
}
No error messages related to the onClick attribute are being displayed, and the current code correctly renders the component.
I also added a 'disabled={false}' attribute to the button to make sure
that was not an issue, but the onClick attribute is still not
responsive.
Try implementing the function as a method.
newTaskHandler = (props) => {
console.log('point reached');
props.state.newTask = true;
}
Then try
onClick={this.newTask(this.props)}
Hope this helps you.
try to call the function:
onClick={newTask()}
And if not try to call it with this.
onClick={this.newTask()}
I'm useing Semantic-ui-react redux and react-router-dom. In my component I have navbar:
<Menu >
<Menu.Item as={Link} to="/" onClick = {this.onNavBarItemCLick()}>
home
</Menu.Item>
<Menu.Item as={Link} to="profile" onClick = {this.onNavBarItemCLick()}>
profile
</Menu.Item>
<Menu.Item as={Link} to="shop" onClick = {this.onNavBarItemCLick()}>
shop
</Menu.Item>
</Menu>
If I click on the one of nav items method onNavBarItemClick fires 3 times. Why it happens?
Because you call method immediately, instead you should only pas handler to onClick attribute:
as={Link} to="shop" onClick = {this.onNavBarItemCLick.bind(this)}>
Solution
You need to replace
onClick = {this.onNavBarItemCLick()}
with
onClick = {() => this.onNavBarItemCLick()} // perserving class's this
or if you prefer the bind notation
onClick = {this.onNavBarItemCLick.bind(this)} // perserving class's this
else
onClick = {this.onNavBarItemCLick} // not perserving class's this
Why it happens
It happens because when you click render() is called again.
React is very efficient in re-rendering, so it's what it's supposed to happen.
The issue with your implementation was that instead of passing a method reference, you were passing the returned value of such method.
Because you should not call it right away in the onClick prop. use this
<Menu.Item as={Link} to="/" onClick = {this.onNavBarItemCLick}>
What ends up happening, is the onNavBarItemCLick being called every time the render function is called when state changes
The onClick prop takes a function as value so what's the problem here ?
<MyComponent onClick={this.handleClick()} />
using this.handleClick() instantly call the function and gives its return value to onClick. What you want here is to give the function itself to onClick like so
<MyComponent onClick={this.handleClick} />
But you'll probably get another error there if this.handleClick uses this as it is not automatically bound in a React class. There are ways to fix this like binding this in the constructor, using an array function for handleClick or directly bind this when passing the function to onClick like
<MyComponent onClick={this.handleClick.bind(this)} />
Going a bit further, you could also return a function in handleClick which here is totally useless. It's only to illustrate :
class MyComponent extends React.Component {
handleClick () {
return () => { console.log('I am triggered on click') }
}
render () {
// We call this.handleClick() which returns the function
// that'll be actually called on click.
return <div onClick={this.handleClick()} />
}
}
I hope this helps
When you do this.onNavBarItemClick(), what happens is that the parenthesis execute the function at that point. Whereas this.onNavBarItemClick will treat it as a variable.
So in the above piece of code, when you do onClick = {this.onNavBarItemClick()}, the function is getting called there itself without the user clicking on it. Whereas if you do onClick = {this.onNavBarItemCLick} the function gets invoked only if you click on it.
You can also do onClick = {()=>this.onNavBarItemClick()}. By doing this you are creating an anonymous function and passing it to onClick.
So you can do either of onClick = {this.onNavBarItemClick} or onClick = {()=> this.onNavBarItemClick()}
I would expect that setting the disabled attribute on a react component would block the onClick handler for that element.
<a role="button"
className={`btn btn-block btn-info`}
disabled={!this.state.readyToView}
href={this.state.selectedObjectLink}
onClick={this.handleLink}
>View</a>
but although the element shows a "disabled" attribute it still registers a click event.
Edit: I should clarify - I handle the click event in handleLink, I want to know why the disabled attribute doesn't remove the handler? Sorry for any confusion.
The problem isn't with disabled; it's with the HTML element a. Anchor <a> cannot have a disabled property (what does that even mean?). Just because you've passed CSS to make the element look like a button, doesn't make it a button. It is still an anchor.
The solution would be either to use something else (like button):
<button
role="button"
className={`btn btn-block btn-info`}
disabled={!this.state.readyToView}
onClick={this.handleLink}
>
View
</button>
You can use this.state.selectedObjectLink inside handleLink if you want to redirect to a page
Or use one of the many other suggestions on this page.
Why not just handle this in handleLink?
handleLink () {
if (!this.state.readyToView) return
// ...
}
If you really want to bind/remove the handler dynamically, you can do something like this:
const clickHandler = this.state.readyToView ? this.handleLink : null
...
<a role="button"
...
...
onClick={clickHandler}
>View</a>
You can add a condition in your click handler, something like this
<a role="button"
className={`btn btn-block btn-info`}
disabled={!this.state.readyToView}
onClick={this.state.readyToView && this.handleLink}
>
View
</a>
jsfiddle
If you are using react version 16 and up
on onClick don't call the method directly use () => method instead like this
const handleRemoveBtnClick = () => {
...
}
<button ...onClick={() => handleRemoveBtnClick} />
Another trick to disable the click to any components is to use useState with boolean value either true to disable or false to resume the click functionality
example
export default const ElementComponent() =>{
//set the initial value of disable click to false
const [disableClick,setDisableClick] = useState(false)
const anotherFunction =() =>{
console.log("I've been run")
}
const handleClick()=>{
//if disableClick is false then run this if block, else don't do anything
if(!disableClick){
anotherFunction()
}
}
return(
<img src="..." onClick={handleClick}/>
)
}
the good thing about this is that we can pass the function as a props to another components and we can run it there, we can even let's say disable a click for let's say 1 second using setTimeout function, there are tons of way you can use this method, hope it helps anyone if you want to use onClick not only on the button element itself