Unable to pass parameter to React Button callback function on click - javascript

I have a material-ui button and am trying to pass some parameter to my callback function on click.
For some reason, the below way is not working.
const myApi = async (param) => {
}
<Button onClick={myApi('text')}
data-testid='my-field'>
<Icon accessibleText="__label__search" name="search" size={12} />
</Button>

Use
onClick = {() => myApi("text")}

Related

Use text that is passed through props, to know which constant is called for button onClick

does anyone know how I can pass the name of the const I want to use for the button onClick here?
So I have two const's defined in my component, what I want to achieve is that each button in a column calls a different const, so I pass the name of the const I want to use through props, but that doesn't work. For example if I pass clickHandler="handleFirstOption"
The column button onClick has to become:
<Button role="group" mt={10} onClick={handleFirstOption}>
Does anyone know how I can accomplish this?
FooterRow.jsx
<FooterColumn
clickHandler="handleFirstOption"
/>
<FooterColumn
clickHandler="handleSecondOption"
/>
FooterColumn.jsx
const handleFirstOption = event => {
updateStep(firstOption);
};
const handleSecondOption = event => {
updateStep(secondOption);
event.preventDefault();
};
<Button role="group" mt={10} onClick={clickHandler}>
Define this inside your FooterColumn:
let handlers = {
handleFirstOption: event => {
updateStep(firstOption);
}
handleSecondOption: event => {
updateStep(secondOption);
event.preventDefault();
}
}
Then you can specify which handler you want using string name from props:
<Button role="group" mt={10} onClick={handlers[clickHandler]}>

React / JSX Function not initialising onClick [duplicate]

I am using the ButtonGroup and Button from ReactStrap. I have set an onClick function when you click one of the buttons:
< ButtonGroup >
<Button>Edit</Button>
<Button onClick={console.log("Print some text")}>Print text</Button>
<Button>Set as default</Button>
</ButtonGroup >
But when I load the page this is what I get:
Before I have even clicked the button. And if I do click it, nothing comes out in the console. Any ideas?
Onclick must be function. You just set onlick as result of console.log("Print some text")
Try this
<Button onClick={() => {console.log("Print some text")}}>Print text</Button>
onClick parameter is evaluated as a callback, so if you pass something that is not a function, is evaluated and executed in the runtime.
Instead, you should pass a function to the onClick parameter:
<Button onClick={() => { console.log("Print some text"); }}>Print text</Button>
Be careful with the inline functions because they are evaluated each time that render is executed, that can be multiple times, each functions is more memory used by the browser.
If you has a class, you can use a arrow fat method:
/* ... */
handleOnClick = () => {
console.log("Print some text");
}
render() {
return (
<ButtonGroup>
<Button>Edit</Button>
<Button onClick={this.handleOnClick}>Print text</Button>
<Button>Set as default</Button>
</ButtonGroup >
);
}
/* ... */
To make it clearer
On any event trigger (onClick, onChange , etc) you must specified a function to call when the event occur
not calling the function right away
Consider this function
ES5:
function callMe() {
console.log("Some text");
}
ES6:
const callMe = () => {
console.log("Some text");
}
if you want to call this function when clicking the button you can't do this
<Button onClick={callMe()}>Print text</Button>
This will call the fuction callMe when the button is loaded once.
What you need to do to make it works is
<Button onClick={callMe}>Print text</Button>
Notice that there is no parenthesis after the function name which indicate that the function is not yet called.

Want to call function by using if/else condition in a button (React)

I have a button and i want to call a particular function if a particular situation is true , if it is not true then i want to call other function .
But i want to handle above scenario in one onClick event .
I have tried this
<button onClick= {addTodo , handleClickOpen}> Add Todo </button>
I thought that first it will check addTodo function and if addTodo doesn't complete its work then handleClickOpen function will be called .
But Button doesn't perform like this.
Would you please suggest some other way ?
Thank you
You can do a simple inline if:
<button onClick= {e => myBooleanCondition ? addTodo(e) : handleClickOpen(e)}> Add Todo </button>
As far as I understood, you can simply call one function on onClick that contains the if/else statement.
const onClick = () => {
if () { //some condition
addTodo();
} else {
handleClickOpen();
}
}
<button onClick= {onClick}> Add Todo </button>
The above syntax can vary as per your code standards/structure.
The way i would do it is using ternary operator
<button onClick= {event => condition ? addTodo(event) : handleClickOpen(event)}> Add Todo </button>
and you can also call the second function which decides which function to operate
<button onClick= {event => handleClick(event)}> Add Todo </button>
now in your js file use this function
handleClick(event){
if(event){
addTodo();
}else{
handleClickOpen();
}
}

React : test a function which is passed as a props and is triggered by the parent

I'm trying to trigger a click event for my test. As this :
describe('Button', function() {
test('is clicked when player two is pending', (props ={}) => {
const mockRandomAdv = sinon.spy();
const tree = shallow(
<FightButton
button="Random adversary"
isPlayerTwoPending={true}
isPlayerOnePending={false}
onClick={mockRandomAdv}
/>
);
tree.find('Button').simulate('click');
//expect(mockRandomAdv.calledOnce).toEqual(true);
console.log(tree.props().children.onClick)
//.not.toBe('fight-button random');
});
});
The first expectation return false so the click is not triggered.
When i console.log() the click event it returns undefined.
Here is my child (which is not the last last child).
<Button
onClick={ () => { this.props.randomAdversary }}
class="fight-button random"
button="Random adversary"
/>
And here is the parent that is calling the child and who describe the method :
class Board extends Component {
constructor(props) {
..my constructor
}
randomAdversary() {
...my function
}
return (<div> <FightButton
isPlayerTwoPending={this.state.adversaryPending}
isPlayerOnePending={this.state.characterPending}
isPlayerOneTheWinner={this.state.heroWin}
isFighting={this.state.fighting}
randomAdversary={this.randomAdversary}
fight={this.fight(100)}
playAgain={this.playAgain()}
/>
</div>
)
}
When i click, the class of my button must change. But the same when i console.log the class, it has no changed. Is something wrong with my test ?
Looking at the button, I don't see calling the function correctly. I'ts actually doing nothing, you need to execute the function like this:
<Button
onClick={ () => { this.props.randomAdversary() }} // Add the `()`
class="fight-button random"
button="Random adversary"
/>

React onClick function fires on render

I pass 2 values to a child component:
List of objects to display
delete function.
I use a .map() function to display my list of objects(like in the example given in react tutorial page), but the button in that component fires the onClick function, on render(it should not fire on render time). My code looks like this:
module.exports = React.createClass({
render: function(){
var taskNodes = this.props.todoTasks.map(function(todo){
return (
<div>
{todo.task}
<button type="submit" onClick={this.props.removeTaskFunction(todo)}>Submit</button>
</div>
);
}, this);
return (
<div className="todo-task-list">
{taskNodes}
</div>
);
}
});
My question is: why does onClick function fire on render and how to make it not to?
Because you are calling that function instead of passing the function to onClick, change that line to this:
<button type="submit" onClick={() => { this.props.removeTaskFunction(todo) }}>Submit</button>
=> called Arrow Function, which was introduced in ES6, and will be supported on React 0.13.3 or upper.
Instead of calling the function, bind the value to the function:
this.props.removeTaskFunction.bind(this, todo)
MDN ref: https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Global_objects/Function/bind
The Problem lies in how you pass your function
At the moment you are not passing the function but Calling it instead:
<Button onClick={yourFunction()} />
You can Fix this in two ways:
<Button onClick={() => yourFunction(params)} />
Or if you dont have any params:
<Button onClick={yourFunction} />
The value for your onClick attribute should be a function, not a function call.
<button type="submit" onClick={function(){removeTaskFunction(todo)}}>Submit</button>
you need to use an arrow function with onClick in order to prevent immediately invoke.
so if your button looks like this :
<button onClick={yourfunctionname()} />
it must be like this :
<button onClick={() => yourfunctionname(params)} />
JSX is used with ReactJS as it is very similar to HTML and it gives programmers feel of using HTML whereas it ultimately transpiles to a javascript file.
Writing a for-loop and specifying function as
{this.props.removeTaskFunction(todo)} will execute the functions
whenever the loop is triggered .
To stop this behaviour we need to return the function to onClick.
The fat arrow function has a hidden return statement along with the bind
property. Thus it returns the function to OnClick as Javascript can
return functions too !!!!!
Use -
onClick={() => { this.props.removeTaskFunction(todo) }}
which means-
var onClick = function() {
return this.props.removeTaskFunction(todo);
}.bind(this);
For those not using arrow functions but something simpler ... I encountered this when adding parentheses after my signOut function ...
replace this <a onClick={props.signOut()}>Log Out</a>
with this <a onClick={props.signOut}>Log Out</a> ... ! 😆
JSX will evaluate JavaScript expressions in curly braces
In this case, this.props.removeTaskFunction(todo) is invoked and the return value is assigned to onClick
What you have to provide for onClick is a function. To do this, you can wrap the value in an anonymous function.
export const samepleComponent = ({todoTasks, removeTaskFunction}) => {
const taskNodes = todoTasks.map(todo => (
<div>
{todo.task}
<button type="submit" onClick={() => removeTaskFunction(todo)}>Submit</button>
</div>
);
return (
<div className="todo-task-list">
{taskNodes}
</div>
);
}
});
I had similar issue, my code was:
function RadioInput(props) {
return (
<div className="form-check form-check-inline">
<input className="form-check-input" type="radio" name="inlineRadioOptions" id={props.id} onClick={props.onClick} value={props.label}></input>
<label className="form-check-label" htmlFor={props.id}>{props.label}</label>
</div>
);
}
class ScheduleType extends React.Component
{
renderRadioInput(id,label)
{
id = "inlineRadio"+id;
return(
<RadioInput
id = {id}
label = {label}
onClick = {this.props.onClick}
/>
);
}
Where it should be
onClick = {() => this.props.onClick()}
in RenderRadioInput
It fixed the issue for me.
It is possible to achieve this even in more readable way than:
<button onClick={() => somethingHere(param)}/>
const Comp = () => {
const [triggered, setTriggered] = useState(false);
const handleClick = (valueToSet) => () => {
setTriggered(valueToSet);
};
return (
<div>
<button onClick={handleClick(true)}>Trigger</button>
<div>{String(triggered)}</div>
</div>
);
};
That way it won't fire the state setter and won't cause too many re-renders compared to <button onClick={setTriggered(true)}/>
which is okay if you don't have any params to pass to the function.
That's because you are calling the function directly instead of passing the function to onClick
If you have passed down onClick={onClickHandler()} then, the function onClickHandler() will be executed during the time of rendering too, the () instructs to execute the function as soon as it is rendered , which is not desired here , instead we use onClick={onClickHandler} , this will execute the onClickHandler only when the specified event occurs. But if we want to pass down a argument along with the function then we can make use of ES6 arrow function.
For your Case :
<button type="submit" onClick={() => this.props.removeTaskFunction(todo)}>Submit</button>
Bit late here but here is the simple answer.
direct approach will trigger by itself due to JS DOM rendering
onClick={this.props.removeTaskFunction(todo)}
anonymous arrow function approach. it will trigger on click
onClick={()=>this.props.removeTaskFunction(todo)}
You are not passing the function as an argument you are calling it directly that why it launches on the render.
HOW TO FIX IT
there are two ways:
First
<Button onClick={() => {
this.props.removeTaskFunction(todo);
}
}>click</Button>
OR
Just bind it
this.props.removeTaskFunction.bind(this,todo);

Categories