Reputation: 125
I have imported a component from a different file and I want to reset my timer if I click on the imported component's elements. Is there a way to tackle this issue or should I write both components in single jsx ?
import {SampleComponent} from "../SampleComponent";
<div>
<SampleComponent onClick = {?????????}/>
</div>
Upvotes: 7
Views: 9047
Reputation: 113
This is what I do:
On the SampleComponent js file, set a prop for onClick on SampleComponent;
Set the onClick property of the button to the onClick prop associated with SampleComponent:
SampleComponent.js:
const SampleComponent = ({ onClick }) => {
//onClick prop to the SampleComponent
return (
//associate onClick property of the button
<button onClick={onClick}>
Button
</button>
);
}
export default SampleComponent;
App.js:
import SampleComponent from "./SampleComponent.js";
function App() {
const handleClick = () => {
//whatever you want to happen when the button is clicked (step 4)
};
//set the onClick property of the component
return (
<SampleComponent onClick={handleClick} />
);
}
export default App;
By doing this, the SampleComponent's prop is 'changed' to handleClick on click and because the button inside it is set to act as the SampleComponent's prop, his 'onClick' will also be set to handleClick;
button --> component
function --> component --> button
And that works with anything: className, label... etc etc. e.g.:
SampleComponent.js:
const SampleComponent = ({ onClick, className, label }) => {
return (
<button className={className} onClick={onClick}> {label} </button>
);
}
export default SampleComponent;
App.js:
import SampleComponent from "./SampleComponent.js";
function App() {
const handleClick = () => {...};
return (
<SampleComponent className='thisClass' onClick={handleClick} label='button' />
);
}
//By doing this you change the buttons' onClick, className and even text
export default App;
Hope this helps :)
Upvotes: 1
Reputation: 988
It's hard to answer your question specifically without more context (like what timer are you wanting to reset). But the answer is no, you do not need to implement both components in the same file. This is fundamental to react to pass props like what you tried to do in your question.
Here is an example.
Say your SampleComponent
looks like the following:
// SampleComponent.jsx
function SampleComponent({ onClick }) { // the argument is an object full of the props being passed in
return (
<button onClick={(event) => onClick(event)}>Click Me!</button>
);
}
and the component that is using SampleComponent
looks like this:
import SampleComponent from '../SampleComponent';
function resetTimer() {
// Add logic to reset timer here
}
function TimerHandler() {
return (
<SampleComponent onClick={() => resetTimer()} />
);
}
Now when you click the button
rendered by SampleComponent
, the onClick
handler passed from TimerHandler
will be called.
A prop on a React component is really just an argument passed into a function
:)
Upvotes: 0
Reputation: 343
If you want to call a function in parent component, whenever an event (such as in your case an onClick
event) occurs in a child component, you will need to pass the parent function as a props.
Here's what it will look like:
class ParentComponent extends React.Component {
handleClick = () => { ... }
render {
return (
<SampleComponent onClick={this.handleClick} />
)
}
}
And here is how your SampleComponent will be:
class SampleComponent extends React.Component {
render {
return (
<div onClick={this.props.onClick}> //to call the function on whole component
<button onClick={this.props.onClick}>Click Me</button> //to call the function on a specific element
</div>
)
}
}
What I have understand so far from your question is that you want to call a function in SampleComponent whenever a click event occurs on it (on SampleComponent).
To do this, here is how your SampleComponent
will look like :
class SampleComponent extends React.Component {
.
.
render() {
handleClick = () => { ... }
return (
<div onClick={this.handleClick}>
...
</div>
)
}
Note: For this you don't need to add onClick in parent.
Upvotes: 2
Reputation: 512
resetTimerHandler = (timer)=>{
timer = 0; or this.setState({timer: 0}) // how ever you are defining timer
}
render(){
let displayTimer;
this.updateTimer(displayTimer)// However you are updating timer
return(
<SampleComponent onClick={this.resetTimerHandler.bind(this,displayTimer)} />)
Without knowing how you are updating your timer I can't really give a specific answer but you should be able to apply this dummy code.
Upvotes: 1
Reputation: 1736
What you can do here is,
import {SampleComponent} from "../SampleComponent";
<div onClick={??????}>
<SampleComponent/>
</div>
Or you can pass the function from your parent component and add click event on top node of the child component.
<div>
<SampleComponent onHandleClick={() => ??????}/>
</div>
Upvotes: 3