Revocation form validation - no event callbacks

I tried to find a good example of form validation in a reaction. I found confirmation by sending events from the parent form to my children and calling the validation method on each of them.

I also found a method by quoting child forms and typing setState for the child after checking the field.

As far as I know, these are anti-patterns, and the response method is a call through requisites callbacks - custom.js custom events for communication with parent nodes

Say I have a component:

 class Main extends React.Component { ... onSubmitHandler() { ... } render() { return ( <FormComponent onSubmit={this.onSubmitHandler.bind(this)}> <InputComponent value="foo" validation="required" /> <input type="submit" value="Save" /> </Form> ); } } class FormComponent extends React.Component { onSubmit() { // TODO: validation } render() { return ( <form onSubmit={this.onSubmit.bind(this)} > {this.props.children} </form> ); } } class InputComponent extends React.Component { constructor(props) { super(props); this.state = { value: props.value } } render() { return ( <input type="text" value={value} ); } } 

I can’t figure out how to validate each input through callbacks passing through the details.

+4
source share
2 answers

Here's a simplified example (Child to Parent):

 var Bar = React.createClass({ validate : function () { var number = React.findDOMNode(this.refs.input).value; this.props.check(number, this.success, this.fail); }, success : function () { alert('Success'); }, fail : function () { alert('Fail'); }, render : function () { return ( <div> <input type='number' min='1' max='20' ref='input'/> <br/> <button onClick={this.validate}>Click me to validate</button> <br/> (Values 1 - 10 are valid, anything else is invalid) </div> ); } }); var Foo = React.createClass({ check : function (number, success, fail) { if (number >= 1 && number <= 10) { success(); } else { fail(); } }, render : function () { return ( <div> <Bar check={this.check} /> </div> ); } }); 

In this example, <Bar/> is a child, and <Foo/> is a parent. <Bar/> is responsible for processing user input, and when the button is pressed, it calls a function from <Foo/> to perform a check, which, upon completion, calls one of two functions in <Bar/> depending on the results.

Here's what it looks like: http://jsbin.com/feqohaxoxa/edit?js,output

- EDIT -

Here is an example for parent to child:

 var Parent = React.createClass({ getInitialState : function () { return({validate : false}); }, click : function () { this.setState({validate : true}); }, done : function () { this.setState({validate : false}); }, render : function () { return ( <div> <button onClick={this.click}>Validate children</button> <br/> <Child num={1} validate={this.state.validate} done={this.done}/> <Child num={2} validate={this.state.validate} done={this.done}/> <Child num={3} validate={this.state.validate} done={this.done}/> </div> ); } }); var Child = React.createClass({ componentWillReceiveProps : function (nextProps) { if (nextProps.validate == true && this.props.validate == false) { var number = React.findDOMNode(this.refs.input).value; if (number >= 1 && number <= 10) { alert("Child " + this.props.num + " valid"); } else { alert("Child " + this.props.num + " invalid"); } this.props.done(); } }, render : function () { return ( <div> <input type="number" min="1" max="20" ref='input'/> </div> ); } }); 

To do this, I use the state of the parent to indicate whether I want to check the validation. Changing the state from false to true, I force a re-rendering that conveys the truth to the children. When the children receive a new support, they check if it is true and if it is different from the last, and check if it is so. After validation, they use a callback to tell the parent rule to return its validation state to false.

Demo: http://output.jsbin.com/mimaya

+1
source

I added the code to yours. In short, what I did was add ref prop to your inputComponent to open its validation function (which I added to inputComponent). The validate function is called when the listener starts. In the end, the validate function calls the isValid callback, which we passed through the details. I think you can do it.

 class Main extends React.Component { ... onSubmitHandler() { ... this.refs.input1.validate(); } render() { return ( <FormComponent onSubmit={this.onSubmitHandler.bind(this)}> <InputComponent ref="input1" value="foo" validation="required" isValid={this.isValidInput} /> <input type="submit" value="Save" /> </Form> ); } isValidInput(someParam) { console.log(someParam); } } class FormComponent extends React.Component { onSubmit() { // TODO: validation } render() { return ( <form onSubmit={this.onSubmit.bind(this)} > {this.props.children} </form> ); } } class InputComponent extends React.Component { constructor(props) { super(props); this.state = { value: props.value } } render() { return ( <input type="text" value={value} ); } validate(){ this.props.isValid(YesOrNo); } } 

I hope this helps

+1
source

All Articles