<Button onClick={submitHandler}>
I have this button which already has an assigned function to its onClick event. I also want to add <Button onClick={() => Toggle()}> this Toggle function into same button. How can I do it?
Simply create a function which calls both of the functions. Assuming submitHandler needs the event object, that will look like:
<Button onClick={(event) => {
submitHandler(event);
Toggle();
})}>
if you want to handle event you need to do onClick={(e) => { submitHandler(e); Toggle(); }.
if you don't want to handle event just do onClick={() => { submitHandler(); Toggle(); }.
First, think of separating your functions you can do something like :
<Button onClick={(e) => handleClick}>
And then create your functions which gonna look like:
const handleClick = (e) => { handleSubmit(e); handleToggle();}
You can later work on each function apart:
const handleSubmit() => { // your code }
const handleToggle() => { // your code }
Related
I am trying to create a submit function on a button. But when I build the application, a typing error appears. I tried different approaches but I don't understand how to solve the error.
This is the error:
I simplified the submit function which still returns the error.
const handleSubmit = ({e}: any) => {
e.preventDefault();
};
#another try
const handleSubmit = (e: any) => {
e.preventDefault();
};
<Button onClick={(e: any) => handleSubmit(e)} />
#another try
<Button onClick={handleSubmit} />
Considering my comment above, something like this should work:
const handleSubmit = () => {
...
// Your handler code
};
<Button onClick={handleSubmit} />
According to the type that you have set for 'e' in fact you did not use the typescript and you create a trick to handle typeScript error and warning so you can write like below:
const handleSubmit = (e) => {
e.preventDefault();
};
<Button onClick={handleSubmit} />
I built this toy problem to replicate an issue I am facing in a larger app. Why does handleClick not fire when the button is clicked?
const Button = () => <button type="button">Click me</button>;
export const App = () => {
const handleClick = () => {
console.log("clicked");
};
return <Button onClick={handleClick} />;
};
You pass onClick={handleClick} as a property to Button but the Button component does not use the property.
const Button = () ... // ⚠️ no onClick property used
You can fix this by responding to the onClick property -
const Button = ({ onClick }) => // ✅
<button type="button" onClick={onClick}> // ✅
Click me
</button>
An obvious improvement would be to respond to the children property as well. This allows the caller of Button to write anything in place of the static Click me -
const Button = ({ onClick, children }) =>
<button type="button" onClick={onClick}>{children}</button>
<Button onClick={handleRegister}>Register</Button>
<Button onClick={handleLogin}>Login</Button>
<Button onClick={handleSave}>Save</Button>
Note children can be passed as a property. Sometimes you will see components use children in this way. Both examples function identically -
const Button = ({ onClick, children }) =>
<button
type="button"
onClick={onClick}
children={children}
/>
Another common thing for Button components like this is to automatically prevent the default event for the onClick handler. We can also accept a type property and set the default to "button" if the caller does not otherwise specify -
const Button = ({ type = "button", onClick, children, preventDefault = true }) =>
<button
type={type}
onClick={e => {
if (preventDefault) e.preventDefault()
onClick(e)
}}
children={children}
/>
<Button type="submit" onClick={handleRegister}>Register</Button>
<Button onClick={handleReset} preventDefault={false} children="Reset" />
so here is what i'm trying to do. I have 3 buttons in material ui and I gave each one of them and id. I want to send the id through a onClick to a single handleclick function that then runs a switch case and determines which button pressed the id and then sets the state accordingly. This is because I want to have so when a button is clicked, it sets a key value that i specifiy depending on which one what clicked. Here is my code below
const [key, setKey] = useState("");
const handleClick = (e: MouseEvent<HTMLElement>) => {
const target = e.target as Element;
const id = target.id;
alert(id);
};
async function register(e: Event) {
e.preventDefault();
try {
const registerData = {
firstName,
lastName,
username,
password,
passwordVerify: passwordConfirm,
key: { key },
};
} catch (err) {
console.error(err);
}
}
<Button
id="btn1"
className={classes.buttonStyle}
onClick={handleClick}
>
Student
</Button>
<Button
id="btn2"
className={classes.buttonStyle}
onClick={handleClick}
>
{" "}
Ta{" "}
</Button>
<Button
id="btn3"
className={classes.buttonStyle}
onClick={handleClick}
>
{" "}
Admin{" "}
</Button>
My problem is that whenever I click the button on the react page, it shows an empty alert sometimes and other times it shows up with the button. Idk why that's the case. the alert is to test if i'm actually getting an id from the button press.
can someone tell me the types I need to be adding for this to work. Thanks
It should be as follows. The correct event triggered is a mouseEvent.
You can access Id with event.currentTarget instead of event.target
import { MouseEvent } from 'react';
...
const handleClick = (e: MouseEvent<HTMLElement>) => {
const id = e.currentTarget.id;
console.log(id);
}
...
<Button
...
onClick={handleClick}
/>
...
Change Event type to MouseEvent<HTMLButtonElement>
import { MouseEvent } from 'react'
// ... some code
const handleClick = (e: MouseEvent<HTMLButtonElement>) => {
const id = e.currentTarget.id;
console.log(id);
}
Further, for a small performance gain, it is better to declare handleClick using useCallback
import { useCallback, MouseEvent } from 'react'
// ... more code
const handleClick = useCallback((e: MouseEvent<HTMLButtonElement>) => {
const id = e.currentTarget.id;
console.log(id);
}, []);
Edit: modify answer after question edits.
so I was getting an empty alert because of the setKey line. Once I removed it, the alert showed the right key (along with changing target to currentTarget. Thanks everyone for the help
I'm relatively new to React and I was working on a button that duplicates a component I created when clicked, but I want to limit the user to only be allowed to click on said button a set number of times (say 4 times) before the button is non-functional/removed. Here's a code snippet if it helps; is this possible? I thought about having a counter, but how would I implement that alongside the button?
Many thanks!
function App() {
const [inputList, setInputList] = useState([]);
const onAddBtnClick = event => {
setInputList(inputList.concat(<Autocomplete items={foods} />));
};
return (
<Fragment>
<div className="foodcompleter">
<Button onClick={onAddBtnClick} variant="primary" size="lg" block>Add Food</Button>
{inputList}
</div>
</Fragment>
);
}
You can basically check if inputList.length === 4, then you disable the button
You can create your component CustomButton with a state that saves the number of clicks and after each state change just validate if the number of clicks is equal to your desired value.
You could remove the event listener after the click
const onKeyDown = (event) => { console.log(event) }
useEffect(() => {
window.addEventListener('keydown', onKeyDown)
return () => { window.removeEventListener('keydown', onKeyDown) }
}, [])
I create REACT component and passes the method to call by pressing the button, using the Redux connect. There is a code:
const PageClientOne = ({onSubmit, onDelete, client}) => {
return(
<form style={styles.enter} onSubmit={_handleSubmit(client,onSubmit)}>
// ... something code
<Button type="submit" theme="success">Save</Button>
<Button type="button"
theme="error" onClick={onDelete(client._id)}>Delete</Button>
</form>
)
}
const _handleSubmit = (client, onSubmit) => {
return event => {
event.preventDefault()
onSubmit(client)
}
}
const mapStateToProps = (state, ownProps) => {
return {
client: state.reducers.clientsState.client
}
}
const mapDispatchToProps = (dispatch) => ({
onSubmit: (client) => {
dispatch(saveClient(client))
},
onDelete: (id) => {
console.log("DELETE")
}
}
export default connect(
mapStateToProps,
mapDispatchToProps
)(PageClientOne)
The problem is that onDelete triggered when the page loads, and not only when clicked on the button. What am I doing wrong?
Its slightly different in React.
Change this,
<Button type="button" theme="error" onClick={onDelete(client._id)}>Delete</Button>
to,
<Button type="button" theme="error" onClick={()=>onDelete(client._id)}>Delete</Button>
Read here for more info,
https://facebook.github.io/react/docs/handling-events.html
(I'm not very familiar with React, so this could be wrong...)
When you create your <form> element, you define the button like this:
<Button type="button" theme="error" onClick={onDelete(client._id)}>Delete</Button>
Code in brackets – {onDelete(client._id)} – gets executed when the element is created (at page load), and the result it evaluates to is inserted into the element, not the code itself. You meant to have a normal onclick attribute; so put the code in quotes "" as in usual HTML:
onclick="onDelete(client._id)"
The issue is in onClick
<Button type="button" theme="error" onClick={onDelete(client._id)}>Delete</Button>
Instead of passing the callback function you are actually calling onDelete at the time of element creation.
Try
<Button type="button" theme="error" onClick={onDelete.bind(this, client._id)}>Delete</Button>
Hope it helps.
I hope my answer is corresponding to your question.
Looks like your delete button was submitting the form as you get the page refreshed.
So, you need to prevent the submit.
const mapDispatchToProps = (dispatch) => ({
onSubmit: (client) => {
dispatch(saveClient(client))
},
onDelete: (evt, id) => {
evt.preventDefault()
console.log("DELETE")
}
}
And on your delete button
<Button type="button" theme="error" onClick={(evt) => onDelete(evt, client._id)}>Delete</Button>