3

I am getting error after taking a React render from something like this

            return (
                React.createElement('form', {
                        onSubmit: this.onSubmit,
                        className: 'ContactForm',
                        noValidate: true
                    },
                    React.createElement('input', {
                        type: 'text',
                        className: errors.name && 'ContactForm-error',
                        placeholder: 'Name',
                        onInput: this.onNameInput,
                        value: this.props.value.name,
                    }),
                    React.createElement('button', {
                        type: 'submit'
                    }, "Add Contact")
                )
            );

to something like this

            function create_input_element(type, fieldname){
                var capital_fieldname = capitalize(fieldname);
                return React.createElement('input', {
                    type: type,
                    className: errors[fieldname] && 'ContactForm-error',
                    placeholder: capitalize(capital_fieldname),
                    onInput: this['on' + capital_fieldname + 'Input'],
                    value: this.props.value[fieldname],
                    autoFocus: true,
                })
            }
        
           create_input_element('text', 'name')

The issue is at this.props.value[fieldname], and even this.props.value.name will break with the same error.

The exact code is

<head>
    <style>
        body {
            font-family: Tahoma, sans-serif;
            margin: 0;
        }

        .ContactView-title {
            font-size: 24px;
            padding: 0 24px;
        }

        .ContactView-list {
            list-style: none;
            margin: 0;
            padding: 0;
            border-top: 1px solid #f0f0f0;
        }

        .ContactItem {
            margin: 0;
            padding: 8px 24px;
            border-bottom: 1px solid #f0f0f0;
        }

        .ContactItem-email {
            font-size: 16px;
            font-weight: bold;
            margin: 0;
        }

        .ContactItem-name {
            font-size: 14px;
            margin-top: 4px;
            font-style: italic;
            color: #888;
        }

        .ContactItem-description {
            font-size: 14px;
            margin-top: 4px;
        }

        .ContactForm {
            padding: 8px 24px;
        }

        .ContactForm>input {
            display: block;
            width: 240px;
            padding: 4px 8px;
            margin-bottom: 8px;
            border-radius: 3px;
            border: 1px solid #888;
            font-size: 14px;
        }

        .ContactForm>input.ContactForm-error {
            border-color: #b30e2f;
        }
    </style>

    <meta name="description" content="Ridiculously Simple Forms with Raw React - Exercise Two">
    <script src="https://cdn.rawgit.com/zloirock/core-js/master/client/shim.min.js"></script>
    <meta charset="utf-8">
    <title>JS Bin</title>
</head>

<body>
    <div id="react-app"></div>
    <script src="https://cdn.jsdelivr.net/react/0.14.0-rc1/react.js"></script>
    <script src="https://cdn.jsdelivr.net/react/0.14.0-rc1/react-dom.js"></script>

    <script>
        /*
         * Components
         */

         function capitalize(str){
             return str.charAt(0).toUpperCase() + str.substring(1)
         }


        var ContactForm = React.createClass({
            propTypes: {
                value: React.PropTypes.object.isRequired,
                onChange: React.PropTypes.func.isRequired,
                onSubmit: React.PropTypes.func.isRequired,
            },

            onEmailInput: function(e) {
                this.props.onChange(Object.assign({}, this.props.value, {
                    email: e.target.value
                }));
            },

            onNameInput: function(e) {
                this.props.onChange(Object.assign({}, this.props.value, {
                    name: e.target.value
                }));
            },

            onSubmit: function(e) {
                e.preventDefault();
                this.props.onSubmit();
            },

            render: function() {
                var errors = this.props.value.errors || {};

                function create_input_element(type, fieldname){
                    var capital_fieldname = capitalize(fieldname);
                    return React.createElement('input', {
                        type: type,
                        className: errors[fieldname] && 'ContactForm-error',
                        placeholder: capitalize(capital_fieldname),
                        onInput: this['on' + capital_fieldname + 'Input'],
                        value: this.props.value[fieldname],
                        autoFocus: true,
                    })
                }

                return (
                    React.createElement('form', {
                            onSubmit: this.onSubmit,
                            className: 'ContactForm',
                            noValidate: true
                        },
                        create_input_element('email', 'email'),
                        create_input_element('text', 'name'),
                        React.createElement('button', {
                            type: 'submit'
                        }, "Add Contact")
                    )
                );
            },
        });


        var ContactItem = React.createClass({
            propTypes: {
                name: React.PropTypes.string.isRequired,
                email: React.PropTypes.string.isRequired,
            },

            render: function() {
                return (
                    React.createElement('li', {
                            className: 'ContactItem'
                        },
                        React.createElement('h2', {
                            className: 'ContactItem-email'
                        }, this.props.email),
                        React.createElement('span', {
                            className: 'ContactItem-name'
                        }, this.props.name)
                    )
                );
            },
        });


        var ContactView = React.createClass({
            propTypes: {
                contacts: React.PropTypes.array.isRequired,
                newContact: React.PropTypes.object.isRequired,
                onNewContactChange: React.PropTypes.func.isRequired,
                onNewContactSubmit: React.PropTypes.func.isRequired,
            },

            render: function() {
                var contactItemElements = this.props.contacts
                    .map(function(contact) {
                        return React.createElement(ContactItem, contact);
                    });

                return (
                    React.createElement('div', {
                            className: 'ContactView'
                        },
                        React.createElement('h1', {
                            className: 'ContactView-title'
                        }, "Contacts"),
                        React.createElement('ul', {
                            className: 'ContactView-list'
                        }, contactItemElements),
                        React.createElement(ContactForm, {
                            value: this.props.newContact,
                            onChange: this.props.onNewContactChange,
                            onSubmit: this.props.onNewContactSubmit,
                        })
                    )
                );
            },
        });



        /*
         * Constants
         */


        var CONTACT_TEMPLATE = {
            name: "",
            email: "",
            description: "",
            errors: null
        };




        /*
         * Model
         */


        // The app's complete current state
        var state = {};

        // Make the given changes to the state and perform any required housekeeping
        function setState(changes) {
            Object.assign(state, changes);

            ReactDOM.render(
                React.createElement(ContactView, Object.assign({}, state, {
                    onNewContactChange: updateNewContact,
                    onNewContactSubmit: submitNewContact,
                })),
                document.getElementById('react-app')
            );
        }

        // Set initial data
        setState({
            contacts: [{
                key: 1,
                name: "James K Nelson - Front End Unicorn",
                email: "[email protected]"
            }, {
                key: 2,
                name: "Jim",
                email: "[email protected]"
            }, ],
            newContact: Object.assign({}, CONTACT_TEMPLATE),
        });



        /*
         * Actions
         */


        function updateNewContact(contact) {
            setState({
                newContact: contact
            });
        }


        function submitNewContact() {
            var contact = Object.assign({}, state.newContact, {
                key: state.contacts.length + 1,
                errors: {}
            });

            if (!/.+@.+\..+/.test(contact.email)) {
                contact.errors.email = ["Please enter your new contact's email"];
            }
            if (!contact.name) {
                contact.errors.name = ["Please enter your new contact's name"];
            }

            setState(
                Object.keys(contact.errors).length === 0 ?
                {
                    newContact: Object.assign({}, CONTACT_TEMPLATE),
                    contacts: state.contacts.slice(0).concat(contact),
                } :
                {
                    newContact: contact
                }
            );
        }
    </script>

</body>

Why can't I generate React.createElement() things in a function?

1

1 Answer 1

1

It's a scope problem. You can learn here how the variable this works .

To solve your problem, you can use call to explicit pass this variable of the scope where the function is being invoked.

The code would look like like this: create_input_element.call(this, 'email', 'email')

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.