Dynamic tag incorrect casing

ThaFlaxx :

I am trying to render different components from react-bootstrap based on the a string in a showModal function in a button, but I am getting Warning: <MyModal/> is using incorrect casing. Use PascalCase for React components, or lowercase for HTML elements.

This snippet does not throw the same warning, but it creates an element, which is lowercased, based on the string in the function.

class Modal extends React.Component {
  render() {
    return (
      <h1>text</h1>
    )
  }
}

class MyButton extends React.Component {
  render() {
    return (
      <button onClick={() => showModal("Modal")}>Show Modal</button>
    )
  }
}

const showModal = (modalName) => {
  const MyModal = modalName
  ReactDOM.render(<MyModal />, document.getElementById("root"));
}

ReactDOM.render(<MyButton />, document.getElementById("root"));
<div id="root"></div>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.6.3/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.6.3/umd/react-dom.production.min.js"></script>

Do you have any ideas?

Daniel :

The issue you are expiring is due to react trying to add an HTML tag name <Modal> instead of the React.Component Modal. The react renderer is trying to render an unknown HTML tag.


More explanation

I did a small refactor of the showModal function to simplify the issue.

const showModal = (modalName) => {
  const MyModal = modalName
  const reactElement = <MyModal />; // equals to React.createElement(MyModal)
  ReactDOM.render(reactElement, document.getElementById("root"));
}

The thing is that the reactElement is not equal to the Modal. The main issue is that you are losing the React.component reference and unable to resole it by only a string.


Prepose solutions

So... what can you do.

  1. Not use string. Just pass the React.Component as a value. (Ya I know its the whole point of the question but React doesn't really work this way).
<button onClick={() => showModal(Modal)}>Show Modal</button>
  1. Use key value pairs. If you still like to use strings to resolve the React.Component you will need to store them in a pairs. where the key is a string and the value is a React.Component
    const bootstrapComp = {
      modal: Modal,
      ...
    }

    ...

    const showModal = (modalName) => {
      const MyModal = bootstrapComp[modalName]
      ReactDOM.render(reactElement, document.getElementById("root"));
    }

Hope this help.

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=29984&siteId=1