簡體   English   中英

如何只允許存在 React 組件的單個實例?

[英]How can I allow only a single instance of a React component to be present?

我正在嘗試構建一個反應功能。

問題是這樣的:我有三個組件 ComponentA、ComponentB、ComponentC。 ComponentC 可以呈現為 ComponentA 或 ComponentB 的子級。

我想要實現的是,在任何時間點,DOM 中都只有一個 ComponentC 實例,可以是 ComponentA 或 ComponentB 的子級,兩者都始終存在。

class ComponentA extends Component {
  render() {
    return (
      <ComponentC />
    );
  }
}

class ComponentB extends Component {
  render() {
    return (
      <ComponentC />
    );
  }
}

class ComponentC extends Component {
  render() {
    return (
      <div>This is ComponentC </div>
    );
  }
}

我試圖構建一種方法來卸載 ComponentC 的任何實例(如果存在),只要它已安裝但無法成功。

有幾種方法可以做到這一點。 想到的最簡單的方法就是檢查DOM是否存在所述節點。 如果它存在,只需渲染任何內容或阻止狀態切換它。

 class MyApp extends React.Component { constructor() { super(); this.state = { showA: false, showB: false }; } toggleA = () => { if(document.getElementById("component_c") && !this.state.showA) return; this.setState((prevState) => ({showA: !prevState.showA})); } toggleB = () => { if(document.getElementById("component_c") && !this.state.showB) return; this.setState((prevState) => ({showB: !prevState.showB})); } render() { return( <div> <div> <button onClick={this.toggleA}>Show/Hide A</button> <button onClick={this.toggleB}>Show/Hide B</button> </div> {this.state.showA && <ComponentA />} {this.state.showB && <ComponentB />} </div> ); } } class ComponentA extends React.Component { render() { return ( <ComponentC parent="A" /> ); } } class ComponentB extends React.Component { render() { return ( <ComponentC parent="B" /> ); } } class ComponentC extends React.Component { render() { return ( <div id="component_c">{"This is ComponentC, rendered from component" + this.props.parent}</div> ); } } ReactDOM.render(<MyApp />, document.getElementById("app")); 
 <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="app"></div> 

使用鈎子實現引用計數器可以完成這項工作:

 function Highlander(Component) { let immortals = 0 return function(props) { const [onlyOne, thereIsOnlyOne] = React.useState(false) React.useEffect(() => { immortals++ if (immortals === 1) { thereIsOnlyOne(true) } () => { immortals-- } }, []) return onlyOne ? <Component { ...props}/> : <React.Fragment></React.Fragment> } } function Test() { return "test" } const OnlyOneTest = Highlander(Test) ReactDOM.render(<React.Fragment> <OnlyOneTest /> <OnlyOneTest /> <OnlyOneTest /> </React.Fragment>, document.getElementById("react"));
 <div id="react"></div> <script src="https://cdnjs.cloudflare.com/ajax/libs/react/17.0.1/umd/react.production.min.js"></script> <script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/17.0.1/umd/react-dom.production.min.js"></script>

將 Highlander 主演為 HoC,它“單例化”組合組件(獲取 Highlander 參考資料?嗯)。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM