繁体   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