Reactjs:使用render方法追加而不是替换

7

我是一名ReactJs的新手,脑海中有很多问题,例如我想在render方法中追加而不是替换内容,

我能否安全简单地这样做?

创建一个临时div:

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

然后使用 appendChild:
 document.getElementById("root").appendChild(temp)

这是一个干净的方法吗?

那应该可以正常工作。但我会在渲染之前添加它。 - Daniel A. White
你能解释一下你想要做这件事的情况吗?也许有一种更“React风格”的方式。 - topic
@topic 我的情况是:每次我点击“添加”按钮时,它应该创建一个新的选项卡,而不会“关闭”现有的选项卡。 - Mehdi Souregi
@DanielA.White 谢谢,我不知道那个。 - Mehdi Souregi
2
@MehdiSouregi 我肯定会用 React 的方式来做,而不是直接操纵 DOM。你可以构建一个具有选项卡数组状态的组件。然后创建一个通过 setState() 向数组添加新选项卡的方法,在此之后组件将被重新渲染。 - topic
@MehdiSouregi,我看到了你关于添加新标签页的评论,请查看我的编辑答案并参考示例。 - loelsonk
2个回答

8

我认为你不应该在React之外改变DOM。而是通过操作状态(state)来触发组件的重新渲染。

以下是一个使用JSX编写的简单示例,采用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>

编辑:

我看到了你的评论。为了添加新的选项卡,我们可以将新添加的选项卡存储在state中。要显示选项卡,我们使用map迭代选项卡数组。

示例:

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>


我正在努力理解你的答案。问题不在话题上: 我正在使用NodeJs,并且我看到你只使用了两个js文件,这足够吗?对于这个新手问题,抱歉 ^^' - Mehdi Souregi
将您的项目分成较小的部分/模块/组件更易于维护,代码变得更易读和理解。像“webpack”这样的工具可以为您处理优化问题。 - loelsonk
@MehdiSouregi,我看到了你关于添加新标签页的评论,请查看我的编辑后的答案及示例。 - loelsonk

0

这里有一个 CodeSandbox,演示了如何用“React方式”来处理它。


如果您在代码中放置了console.log,它仍然会重新呈现先前添加的选项卡。 - Diego Fortes

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接