Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Reactjs : Append instead of replacing with render method

I am new to ReactJs, and I am having lots of questions in my mind, for instance I want to append instead of replacing with render method,

Can I safely and simply do this ?

Creating a temporary div :

var temp = document.createElement('div');
ReactDOM.render(<NewElement />, temp);

and then appendChild :

 document.getElementById("root").appendChild(temp)

Is it a clean way to do it ?

like image 577
Mehdi Souregi Avatar asked Jun 17 '18 20:06

Mehdi Souregi


1 Answers

I don't think you should mutate DOM outside react. Instead of manipulating the DOM, manipulate state which will trigger new render of your component.

Simple example with JSX, written in ES6:

const MyHiddenComponent = (props) => (
  <div>
    Hello {props.name}
  </div>
)

class App extends React.Component {
 state = { toggle: false };
 
 handleToggle = () => this.setState({ toggle: !this.state.toggle });
 
 render() {
  return (
    <div>
      <button
        onClick={this.handleToggle}>{this.state.toggle ? 'hide' : 'show'}</button>
        {/* Show "Mark" only when state.toggle is true */}
        {this.state.toggle && (
          <MyHiddenComponent name="Mark" />
        )}
        {/* tenary operator */}
        {/* Show "Tom" only when state.toggle is false */}
        {/* Instead of null you can place any JSX */}
        {!this.state.toggle ? (
          <MyHiddenComponent name="Tom" />
        ) : null}
    </div>
  )
 }
}

ReactDOM.render(<App />, document.getElementById('root'));
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.min.js"></script>


<div id="root"></div>

EDIT:

I read your comment. To add new tabs we could store newly added tabs inside state. To display our tabs we iterate tabs array using map.

Example:

class AddNewTab extends React.Component {

   handleSubmit = (e) => {
     e.preventDefault();
          
     // get value
     const inputValue = this.refs.name.value;
     
     // we can also interrupt here if no value
     if (!inputValue) { return false }
     
     console.log('inputValue', inputValue);
     
     this.props.onAdd({
       name: inputValue
     })
     
     // reset input when we are done
     this.refs.name.value = '';
     
   }
   render() {
     return (
       <form 
         onSubmit={this.handleSubmit} 
         style={{ marginBottom: '20px' }}>
          <h1>Add new tab</h1>
          <input
            ref="name"
            type="text" 
            name="dupa" 
            placeholder="type new name" 
          />
          <button type="submit">Add new tab</button>
       </form>
     )
   }
}
const Tabs = (props) => {
 return (
   <div>
     {props.tabs.map((tab, i) => (
        <div key={tab.name + i}>{i + 1} {tab.name}</div>
     ))}
   </div>
 )
}


class App extends React.Component {
     state = { tabs: [
        { name: 'Details'},
        { name: 'Route'}
     ]};
     
     // setState triggers re-render
     handleAddNewTab = (newTab) => {
      // don't add anything if newTab.name is empty
      if (!newTab.name) { return false }
      
      this.setState({ tabs: [...this.state.tabs, newTab] });
     }
  
     
     render() {
      return (
        <div>
           <AddNewTab onAdd={this.handleAddNewTab} />
           {
             this.state.tabs.length ? (
                <Tabs tabs={this.state.tabs} />
             ) : (
               <div>No tabs</div>
             )
           }
        </div>
      )
     }
    }

    ReactDOM.render(<App />, document.getElementById('root'));
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.min.js"></script>

<div id="root"></div>
like image 57
loelsonk Avatar answered Sep 29 '22 11:09

loelsonk