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}/>"
}
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 ponent 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 ing from. Any ideas?
Share Improve this question asked Dec 17, 2018 at 8:34 oolongloopoolongloop 1351 gold badge4 silver badges12 bronze badges4 Answers
Reset to default 3You can not create React ponents 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 ponent'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 ponent 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./ajax/libs/react/16.0.0/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare./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/docs/introducing-jsx.html
And you can learn more here about the state of your ponents : https://reactjs/docs/state-and-lifecycle.html
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}/>
}
}
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 ponent's state will cause a re-render so it should pletely 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
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>
}
}