javascript - 确保组件只能是特定父组件的子组件

标签 javascript reactjs

基本上,我希望能够定义一个组件列表,这些组件可以紧接在组件层次结构中的子组件之上。有没有一种程序化的方法来检查这个?

列表基本上是类的数组,例如

const allowed_parents  = [Parent1, Parent2, Parent3];

然后

<UnListedParent>
  .
  .
  .
  <Child />
</UnListedParent>

应该抛出一个错误

最佳答案

您不能使用任何已知的公共(public) React API 从子项直接访问父项。

当然有一些“hacky”方法,例如,在父级上createRef,然后使用React.Children.map 将其传递给子级,以及React.cloneElement 以编程方式,但这是一个糟糕的设计,我什至不打算在这里发布它,以免与该代码相关联:D

不过,我认为更好的方法更符合 React 哲学和单向自上而下的流程,是使用 HigherOrderComponent 包装的“允许的父项”的组合,将特定标志传递给他们“允许” child ,然后检查 child 是否存在标志,否则会出错。

这可能大约是 this

import React, { useState } from "react";
import ReactDOM from "react-dom";

const Child = ({ isAllowed }) => {
  if (!isAllowed) {
    throw new Error("We are not allowed!");
  }

  return <div>An allowed child.</div>;
};

const allowParentHOC = Wrapper => {
  return ({ children, ...props }) => {
    return (
      <Wrapper {...props}>
        {React.Children.map(children, child =>
          React.cloneElement(child, {
            isAllowed: true
          })
        )}
      </Wrapper>
    );
  };
};

const Parent1 = allowParentHOC(props => <div {...props} />);
const Parent2 = allowParentHOC(props => <div {...props} />);

const UnListedParent = ({ children }) => children;

class ErrorBoundary extends React.Component {
  state = { hasError: false };

  componentDidCatch(error, info) {
    this.setState({ hasError: true, info });
  }

  render() {
    if (this.state.hasError) {
      // You can render any custom fallback UI
      return (
        <>
          <h1>This Child was not well put :(</h1>
          <pre>{JSON.stringify(this.state.info, null, 2)}</pre>
        </>
      );
    }
    return this.props.children;
  }
}

class App extends React.Component {
  state = {
    isUnAllowedParentShown: false
  };

  handleToggle = () =>
    this.setState(({ isUnAllowedParentShown }) => ({
      isUnAllowedParentShown: !isUnAllowedParentShown
    }));

  render() {
    return (
      <>
        <button onClick={this.handleToggle}>Toggle Versions</button>
        {this.state.isUnAllowedParentShown ? (
          <UnListedParent>
            <Child />
          </UnListedParent>
        ) : (
          <>
            <Parent1>
              <Child />
            </Parent1>
            <Parent2>
              <Child />
            </Parent2>
          </>
        )}
      </>
    );
  }
}

export default App;

const rootElement = document.getElementById("root");
ReactDOM.render(
  <ErrorBoundary>
    <App />
  </ErrorBoundary>,
  rootElement
);

关于javascript - 确保组件只能是特定父组件的子组件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54673496/

相关文章:

javascript - 如何获取偶数数组索引并更改其背景颜色

javascript - 尝试更新 React Router 4.0.0 但遇到问题

javascript - 如何处理前端的标准错误对象?

javascript - 如何在父元素的帮助下找到子元素?

javascript - ('connect' 上的 NodeJS 事件)错误

reactjs - 部署具有dockerized前端和dockerise后端镜像的应用程序

reactjs - 使用 `history.goBack()`时如何定义状态

ios - React Native - PhaseScript执行错误

javascript - 如何对 DOM 操作进行单元测试(使用 jasmine)

javascript - 在移动设备上来不及使用 display none, block