Warning: input is a void element tag and must not have `children` or use `props.dangerouslySetInnerHTML`. Check the render method of null
Asked Answered
A

1

7

I am trying to render the errors in the form if the ajax call to the form URL fails. Below is my Admin component:

#app/assets/javascripts/components/admin.js.coffee
@Admin = React.createClass
#  propTypes: ->
#    emailVal: React.PropTypes.string.isRequired

  getInitialState: ->
    edit: false
    errorTexts: []

  handleToggle: (e) ->
    e.preventDefault()
    @setState edit: [email protected]
    @setState errorTexts: []

  handleDelete: (e) ->
    e.preventDefault()
    # yeah... jQuery doesn't have a $.delete shortcut method
    $.ajax
      method: 'DELETE'
      url: "/admins/#{ @props.admin.id }"
      dataType: 'JSON'
      success: () =>
        @props.handleDeleteAdmin @props.admins

  handleEdit: (e) ->
    e.preventDefault()
    data = email: ReactDOM.findDOMNode(@refs.email).value
    # jQuery doesn't have a $.put shortcut method either
    $.ajax
      method: 'PUT'
      async: false
      url: "/admins/#{ @props.admin.id }"
      dataType: 'JSON'
      data:
        admin: data
      error: (data, status, xhr) =>
        errorTexts = []
        for key, value of data.responseJSON
          errorText = "#{key} #{value.toString()}"
          errorTexts.push errorText
        @replaceState errorTexts: errorTexts
        @setState edit: true
      success: (data, status, xhr) =>
        @setState edit: false
        @props.handleEditAdmin @props.admin, data

  adminRow: ->
    dom.tr null,
      dom.td null, @props.admin.email
      dom.td null,
        dom.a
          className: 'btn btn-default'
          onClick: @handleToggle
          'Edit'
        dom.a
          className: 'btn btn-danger'
          onClick: @handleDelete
          'Delete'

  adminForm: ->
    dom.tr null,
      dom.td null,
        dom.input
          className: 'form-control'
          type: 'text'
          defaultValue: @props.admin.email
          ref: 'email'
          for errorText, index in @state.errorTexts
            React.createElement AdminError, key: index, errorText: errorText
      dom.td null,
        dom.a
          className: 'btn btn-default'
          onClick: @handleEdit
          'Update'
        dom.a
          className: 'btn btn-danger'
          onClick: @handleToggle
          'Cancel'

  render: ->
    if @state.edit
      @adminForm()
    else
      @adminRow()

The corressponding AdminError component is:

#app/assets/javascripts/components/adminerror.js.coffee
@AdminError = React.createClass

  getDefaultProps: ->
    errorText: ""

  render: ->
    dom.div
      className: 'help-block'
      @props.errorText

While debugging I am getting the correct value of @props.errorText as "email is invalid". But it is not getting rendered on the page and I am geeting this warning in console: "Warning: input is a void element tag and must not have children or use props.dangerouslySetInnerHTML. Check the render method of null." Attached is the screenshot of both the error and the page. enter image description hereenter image description here

I tried changing the AdminError component as follows, but it didn't work:

#app/assets/javascripts/components/adminerror.js.coffee
@AdminError = React.createClass

  getDefaultProps: ->
    errorText: ""

  render: ->
    dom.div
      className: 'help-block'
      dangerouslySetInnerHTML: __html: marked(@props.errorText.toString(), {saitize: true})

When I set a debug point at the line returning dangerouslySetInnerHTML, I correctly get the value of @props.errorText as "email is invalid" and value of marked(@props.errorText.toString()) as "

email is invalid

".. but still the help-block for error is not rendered at all.

UPDATE: Made the following changes in the AdminError component

app/assets/javascripts/components/adminerror.js.coffee

@AdminError = React.createClass

  getDefaultProps: ->
#    errorText: ""
    errorTexts: []

  render: ->
    for errorText in @props.errorTexts
      dom.div
        className: 'help-block'
        errorText

and in the Admin component, made the following changes to the adminform method:

if(@state.errorTexts.length>0)
            dangerouslySetInnerHTML: {
              __html: ReactDOMServer.renderToString(
  #              for errorText, index in @state.errorTexts
                React.createElement AdminError, errorTexts: @state.errorTexts
              )
            }

not getting the warning anymore, but instead getting the following error:

Uncaught Invariant Violation: ReactCompositeComponent.render(): A valid ReactComponent must be returned. You may have returned undefined, an array or some other invalid object.
Ammunition answered 12/3, 2016 at 10:28 Comment(0)
P
8

Warning: input is a void element tag and must not have children ...

A dom.input may not have child elements.

But this code is trying to render error messages as children of a dom.input:

  dom.td null,
    dom.input
      className: 'form-control'
      type: 'text'
      defaultValue: @props.admin.email
      ref: 'email'
      # These are being rendered as children of the input: 
      for errorText, index in @state.errorTexts
        React.createElement AdminError, key: index, errorText: errorText

Can you render those error messages somewhere else? For example, as siblings of the input:

  dom.td null,
    dom.input
      className: 'form-control'
      type: 'text'
      defaultValue: @props.admin.email
      ref: 'email'
    for errorText, index in @state.errorTexts
      React.createElement AdminError, key: index, errorText: errorText
Permenter answered 14/3, 2016 at 15:4 Comment(4)
That sounds convincing to me, wasted whole day on this. Let me try, thanks!Ammunition
Thanks a ton man, it really worked. I am grateful to you, I was getting dyslexic over this error with the passage of time :pAmmunition
you made my day :DAmmunition
Very good solution @rmosolgo, You fixed easily my is a void element tag and must not have children or use props.dangerouslySetInnerHTML. Check the render method of nullForswear

© 2022 - 2024 — McMap. All rights reserved.