简体   繁体   中英

Refs are empty in a form container

What I'm trying to do is have a Form react component which has a couple methods to check if all the input elements inside are valid.

What I've tried is the following:

var FormContainer = React.createClass({
        getDefaultProps: function() {
            return {
                elements: []
            };
        },
        getInitialState: function() {
            return {
                errors: {}
            };
        },
        className: function() {
            return 'form-container';
        },
        isValid: function() {
            var valid = true,
            self = this;

            this.props.elements.forEach(function(ref){
                if (!self.refs[ref].isValid()){
                    valid = false;
                }
            });

            return valid;
        },
        render: function() {
            var self = this;

            return (
                <form className={self.className()}>
                    {self.props.children}

                    <span>Things be valid: </span> <span>{self.isValid()}</span>
                </form>
            );
        }
    });

And it has an Input type as well:

var Input = React.createClass({
        getDefaultProps: function() {
            return {
                type: 'text'
            };
        },
        getInitialState: function() {
            return {

            };
        },
        className: function() {
            return 'form-input';
        },
        isValid: function() {
            return false;
        },
        render: function() {
            var self = this;

            return (
                <input type={self.props.type} className={self.className()} />
            );
        }
    });

And then this is how I would implement it:

<Form elements={["date"]}>
    <Input ref="date" type="date"></Input>
</Form>

The magic happens in the FormContainer isValid method. What I want to do is for each input name thats added to the elements array, to be able to get the reference to it and call it's own isValid method.

However I see that self.refs is empty when I try to call it here if (!self.refs[ref].isValid()) . I'm new to React so I'm not quite sure I understand the refs bit, but I thought that any Children of my <Form> that had a ref would be able to be accessed through the <Form> itself. How can I fix this or do it a better way? The point is to gather up all the child elements and check their validity in one place at the Form level.

Your code works . Your problem is that when isValid() is called

<span>Things be valid: </span> <span>{self.isValid()}</span>

React hasn't finished parsing the structure yet and thus this.refs will be an empty object which is why you should refrain from checking this.refs inside the render() function.

The docs are quite clear about this.

Never access refs inside of any component's render method - or while any component's render method is even running anywhere in the call stack.

I would move the isValid() functionality to be used when either submitting or actually manipulating the form.

JSFiddle demo

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM