2017-01-27 5 views
2

я получаю ошибку после взятия реакции render от чего-то вроде этогоreactjs: Uncaught TypeError: Не удается прочитать свойство «значение» неопределенной

  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") 
       ) 
      ); 

к чему-то вроде этого

  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') 

вопрос является на this.props.value[fieldname], и даже this.props.value.name будет ломаться с той же ошибкой.

Точный код

<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 (!/[email protected]+\..+/.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> 

Почему я не могу генерировать React.createElement() вещи в функции? Спасибо

+0

Каждая функция имеет свою собственную 'this' значение (кроме функции стрелка). 'this' внутри' create_input_element' не ссылается на ваш экземпляр компонента. Посмотрите на [Как получить доступ к правильному 'this' внутри обратного вызова?] (Http://stackoverflow.com/q/20279484/218196) –

ответ

1

Это проблема с прицелом. Вы можете learn here how the variable this works.

Чтобы решить вашу проблему, вы можете использовать call в явном переходе this переменной области действия, в которой выполняется эта функция.

код будет выглядеть так: create_input_element.call(this, 'email', 'email')

Смежные вопросы