Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Show/Hide ReactJS components without losing their internal state?

I've been hiding/showing react components by not rendering them, for example:

render: function() {   var partial;   if (this.state.currentPage === 'home') {     partial = <Home />;   } else if (this.state.currentPage === 'bio') {     partial = <Bio />;   } else {     partial = <h1>Not found</h1>   }   return (     <div>       <div>I am a menu that stays here</div>       <a href="#/home">Home</a> <a href="#/bio">Bio</a>       {partial}     </div>   ); } 

but just say that the <Bio/> component has lots of internal state. Everytime I recreate the component, it loses it's internal state, and resets to it's original state.

I know of course that I could store the data for it somewhere, and pass it in via props or just globally access it, but this data doesn't really need to live outside of the component. I could also hide/show components using CSS (display:none), but I'd prefer to hide/show them as above.

What's the best practice here?

EDIT: Maybe a better way to state the problem is to use an example:

Ignore React, and assume you were just using a desktop app that had a configuration dialog with a Tab component called A, which has 2 tabs, named 1 and 2.

Say that tab A.1 has an email text field and you fill in your email address. Then you click on Tab A.2 for a second, then click back to Tab A.1. What's happened? Your email address wouldn't be there anymore, it would've been reset to nothing because the internal state wasn't stored anywhere.

Internalizing the state works as suggested in one of the answers below, but only for the component and it's immediate children. If you had components arbitrarily nested in other components, say Tabs in Tabs in Tabs, the only way for them to keep their internal state around is to either externalize it somewhere, or use the display:none approach which actually keeps all the child components around at all times.

It just seems to me that this type of data isn't data you want dirtying up your app state... or even want to even have to think about. It seems like data you should be able to control at a parent component level, and choose to either keep or discard, without using the display:none approach and without concerning yourself with details on how it's stored.

like image 508
Brad Parks Avatar asked Dec 31 '14 15:12

Brad Parks


People also ask

How do you show hide components in React?

Display button text by state valueDisplay text “Hide Component” when show is true. Display text “Show Component” when show is false.

How do you hide a component in React without unmounting?

{display: 'none'} does not unmount the component. It works fine for me.


2 Answers

One option would be to move the conditional inside the component itself:

Bio = React.createClass({     render: function() {         if(this.props.show) {             return <p>bio comp</p>         } else {             return null;         }     } });  <Bio show={isBioPage} /> 

Whether this is "best practise" or not probably depends on the exact situation.

like image 174
Colin Ramsay Avatar answered Sep 24 '22 16:09

Colin Ramsay


Unfortunately, style={{display: 'none'}} trick only works on normal DOM element, not React component. I have to wrap component inside a div. So I don't have to cascade the state to subcomponent.

<div className="content">   <div className={this.state.curTab == 'securities' ? 'active' : ''}>     <Securities />   </div>   <div className={this.state.curTab == 'plugins' ? 'active' : ''}>     <Plugins />   </div> </div> 
like image 37
osamu Avatar answered Sep 25 '22 16:09

osamu