2

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?

4 Answers 4

3

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

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

2 Comments

Thanks so much! This is exactly what I needed help with. Cheers
Glad I could help :)
1

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}/>
      }
  }

Comments

1

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

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

Comments

1

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>
}



}

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.