React 检查来自包装组件的访问

问题描述 投票:0回答:2
javascript reactjs react-redux
2个回答
0
投票

您可以通过多种方式做到这一点。如果您想保持类似的流程(使用访问包装器),那么您应该让包装器本身处理单击以有条件地呈现按钮。

这是一种简单的方法来做到这一点(如上所述,有很多方法可以做到这一点,如果您想要不同的版本,请告诉我):

import React from "react";

const AccessControl = ({ hasAccess, handleClick, children }) => {
    const handleButtonClick = () => {
        if (hasAccess) {
            handleClick();
        } else {
            console.log('Access denied');
        }
    };

    return (
        <div>
            {hasAccess ? (
                children
            ) : (
                <button disabled onClick={handleButtonClick}>
                    Access Denied
                </button>
            )}
        </div>
    );
};

export default AccessControl;

用法

<AccessControl hasAccess={checkUserAccess()}>
   <UltimateButton
     btntext="+ New document"
     classes="btn-primary"
     handleClick={create_new_doc}
   />
</AccessControl>

0
投票

看来您克隆子组件的想法是正确的。

克隆子组件并重新注入一个“装饰”的

handleClick
属性,该属性首先调用
checkUserAccess
,如果此函数返回 true 或确认用户具有访问权限,则它将调用最初传递的
handleClick
回调。

示例:

const AccessControl = ({ children }) => {
  const checkUserAccess = () => {
    // Compute hasAccess
    console.log(hasAccess ? "Access allowed" : "Access denied");
    return hasAccess;
  };

  return Children.map(children, (child) =>
    cloneElement(child, {
      handleClick: (e) => checkUserAccess() && child.props.handleClick(e)
    })
  );
};

演示

const AccessControl = ({ children, hasAccess }) => {
  const checkUserAccess = () => {
    console.log(hasAccess ? "Access allowed" : "Access denied");
    return hasAccess;
  };

  return React.Children.map(children, (child) =>
    React.cloneElement(child, {
      handleClick: (e) => checkUserAccess() && child.props.handleClick(e)
    })
  );
};

const UltimateButton = ({ btntext, handleClick }) => (
  <button type="button" onClick={handleClick}>
    {btntext}
  </button>
);

const App = () => {
  const create_new_doc = () => console.log("create_new_doc");
  
   return (
    <div className="App">
       <UltimateButton
        btntext="No Access Control + New document"
        classes="btn-primary"
        handleClick={create_new_doc}
      />

      <AccessControl hasAccess>
        <UltimateButton
          btntext="Has access + New document"
          classes="btn-primary"
          handleClick={create_new_doc}
        />
      </AccessControl>

      <AccessControl>
        <UltimateButton
          btntext="No access + New document"
          classes="btn-primary"
          handleClick={create_new_doc}
        />
      </AccessControl>
    </div>
  );
};

const rootElement = document.getElementById("root");
const root = ReactDOM.createRoot(rootElement);

root.render(
  <React.StrictMode>
    <App />
  </React.StrictMode>
);
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/18.2.0/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/18.2.0/umd/react-dom.production.min.js"></script>
<div id="root" />

© www.soinside.com 2019 - 2024. All rights reserved.