简体   繁体   中英

How to render a component using innerHTML in React jsx

I'm currently writing functionality that will toggle between two views, graph and list. two is the name of the class of the view's container.

  toggleGraphView() { const two = document.getElementsByClassName('two')[0]; two.innerHTML = '<span>Graph View!</span>' } toggleListView() { const two = document.getElementsByClassName('two')[0]; two.innerHTML = "<ShotLog shotLog={this.state.shotLog}/>" } 

The component switches to the graph view text just fine ('Graph View!') but when I try to switch back to list view, I get nothing. After firing toggleListView, in chrome tools the two container contains <shotlog shotlog="{this.state.shotLog}/"></shotlog> . I need it to look like <ShotLog shotLog={this.state.shotLog}/> in order to pass props correctly.

I'm not sure where the extra quotations are coming from. Any ideas?

I am not expert of ReactJS, but I think you should return proper content instead of trying to change it via JS:

  toggleView() {
      if (this.isGraphView()) {
          return <span>Graph View!</span>;
      } else {
          return <ShotLog shotLog={this.state.shotLog}/>
      }
  }

You can not create React components by putting them into strings, using JSX, your code can be shortened to the following :

this.state.showGraph ? <span>Graph View!</span> : <ShotLog shotLog={this.state.shotLog} />

Using a ternary condition, you can decide what to render depending on the value of a variable, showGraph

showGraph will be stored in your component's state, accessible via this.state , when you want to change the value of something in your state, you will have to call setState , this will cause your component to rerender everything on your screen and show you what you want

Working example :

 class ShotLog extends React.Component { render() { return <div>Hi I'm a ShotLog</div> } } class App extends React.Component { constructor(props){ super(props) this.state = { showGraph: true } } handleClick = ev => { this.setState({ showGraph: !this.state.showGraph }) } render() { return ( <div> {this.state.showGraph ? <span>Graph View!</span> : <ShotLog />} <button onClick={this.handleClick}>Switch me !</button> </div> ) } } ReactDOM.render( <App/>, document.getElementById('react') ) 
 <script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.0.0/umd/react.production.min.js"></script> <script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.0.0/umd/react-dom.production.min.js"></script> <div id="react"></div> 

You will find the basics of JSX on the following official documentation : https://reactjs.org/docs/introducing-jsx.html

And you can learn more here about the state of your components : https://reactjs.org/docs/state-and-lifecycle.html

In conjunction with @Justinas's answer, you can try doing a conditional render instead of doing it with pure JS. You can try something like this:

MyComponent extends React.Component {
  constructor(props) {
      super(props);
      this.state = {currView: 'graph'};
  }

  handleToggle() {
      if (this.state.currView === 'graph') {
          this.setState({currView: 'otherView'});
      } else {
          this.setState({currView: 'graph'});
      }
  }

  render() {
      if(this.state.currView === 'graph') {
          // render your 'graph' view
      } else {
          // render some other view
      }
   }
}

A change to the component's state will cause a re-render so it should completely change whatever was previously there. Just make sure you have something that can toggle or update the state :)

PS Sorry if I made some mistakes in the react related syntax. No IDE right now lol

Instead of trying to access the dom directly using document.getElementsByClassName, you can use react way to toggle the view. You can take reference to my example below.

class TestComponent 
{

constructor(props) {
  super(props); 
  this.state = {
    view: 'list', 
    shotLog: someVal
  }

  handleToggle() {
     const modifiedView= this.state.view == 'graph'? 'list': 'graph'; 
     this.setState(() => {
      return {view: modifiedView}; 
     });

  }

}


render() {
     const {view, shotLog} = this.state;
     <div> 
       <button onClick={this.handleToggle}> Toggle </button> 

       {view == 'graph'} && <span> Graph View! </span> 
       {view == 'list'} && <ShotLog shotLog={shotLog} /> 


     </div>
}



}

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