Reputation: 1840
Let's say I have a reactJS component with a render function as something like this:
render(){
return(
<div>
<OnBoardingHeader title={title} subTitle={subtitle} modalFlag={modalFlag}></OnBoardingHeader>
<OnBoardingStepsHandler displayContent={this.state.displayContent} modalFlag={modalFlag}></OnBoardingStepsHandler>
<div className={modalFlag?"onBoarding-modal actions":"ui center aligned container"}>
<div className="ui left labeled icon button" onCLick={this.showPrevious}>
Pre
<i className="left arrow icon"></i>
</div>
<div className="ui right labeled icon button" onClick={this.showNext}>
Next
<i className="right arrow icon"></i>
</div>
</div>
</div>
)
}
On click of the Next and the Previous button, I change the value for displayContent
, Which says what need to be there in my content section.
displayContent is another react component.
Now there is a scenario, where before changing this displayContent, I need to access the values inside my displayContent
.
I mean, let's say we have a form at step one, now on click next
I want to validate this form, only then proceed to step two
, in other sense call my next function.
Now, this form has this own validation function which I need to call. Similarly, the other steps have there own validation function which I need to call before I move to the next step.
The scenario is very similar to this,https://gist.github.com/jamesgpearce/53a6fc57677870f93248
except, the control of my next
and previous
is with the parent. Not with the child.
Now, My question is how do I access my child's components function inside my parent component. I am not sure if this is advisable to do. My restriction is, I don't want my next and previous controls with the child.
Any suggestion?
Upvotes: 1
Views: 6552
Reputation: 160181
Why do you specifically need to access the child components?
Pass a handler to the child uses (possible after validating the slide) to navigate. Roughly (very):
In the parent:
render = () => {
// ...
<SomeChildComponent nextHandler={this.nextHandler} />
// ...
}
In the child:
// ...
validate = () => {
if (whateverValid()) {
this.props.nextHandler();
}
}
// ...
The parent's nextHandler
sets whatever state is required, which re-renders, which might show the next slide, show a summary, whatever.
We implemented a front/back/up/down wizard slider using essentially this mechanism, with the slide declarations in a standalone JS object, with either a string or a function to indicate what the next and previous slide components were. (The function option is if we need to check wizard state and go to an arbitrary slide based on current wizard state.)
If the buttons must be in the parent, then you have an additional step.
(Again, this is a pretty rough estimate.)
In the parent
validationHandler = (isCurrentStepValid) => {
this.setState({ isCurrentStepValid });
}
nextHandler = () => {
if (this.state.isCurrentStepValid) {
// Handle valid state, e.g., advance wizard
} else {
// Handle invalid state, e.g., don't advance wizard
}
}
render = () => {
<SomeChildComponent validationHandler={this.validationHandler} />
<NextButton onClick={this.nextHandler} />
}
In the child
isComponentValid = () => {
return whateverValidationRequired;
}
validate = () => this.props.validationHandler(this.isComponentValid());
Upvotes: 0
Reputation: 702
I built my own wizard component where your requirements sound similar to what I had to do to it. Basically each child component does its own validation internally and should execute this.props.onValid and this.props.onInvalid along with some useful information you wanna bubble up to the parent after each validation. And as the parent you inject a callback to them to see if the particular content(child) has passed the validation test internally.
//parent
export default () => {
return <Child onValid={onChildValid} onInvalid={onChildInvalid}/>;
}
//child
export default ({ onValid, onInvalid }) => {
//do validation based on user activity
//call onValid/onInvalid whenever the validation is done
}
You can do a lot more like onDirty etc to see if certain things have even changed or not by the user.
Upvotes: 1