1

我想创建一个高阶组件来处理它的子级根据传递的permissions属性呈现的方式。

这是我现在所拥有的:

import React from "react";
const PERMISSION_VIEW = 1;
const PERMISSION_EDIT = 1 << 1;

// A High-Order Component that adds visual feedback according to the
// permissions prop that gets passed to it    
function withPermissions(Component) {
  const wrapper = (props, ref) => {
    const { permissions } = props;

    // Do not apply any permissions handling if we don't
    // pass any permissions
    if (permissions === undefined) {
      return <Component {...props} forwardedRef={ref} />;
    }

    const propChanges = [];
    let afterElements = [];

    if ((permissions & PERMISSION_VIEW) === 0) {
      // We'll assume that the data is already filtered from the server
      afterElements.push(
        <span key={0}>You do not have permissions to view this field</span>
      );
    }

    if ((permissions & PERMISSION_EDIT) === 0) {
      afterElements.push(
        <span key={1}>You do not have permissions to edit this field</span>
      );
      propChanges.push({ readOnly: true, disabled: true });
    }
    props = Object.assign({}, props, ...propChanges);
    return (
      <React.Fragment>
        <Component {...props} forwardedRef={ref} /> {afterElements}
      </React.Fragment>
    );
  };

  // Give this component a more helpful display name in DevTools.
  // e.g. "ForwardRef(logProps(MyComponent))"
  const name = Component.displayName || Component.name;
  wrapper.displayName = `withPermissions(${name})`;

  return React.forwardRef(wrapper);
}

这是一个使用示例

function Data(props) {
  return props.value || "";
}
Data = withPermissions(Data);

const ref = React.createRef();


const App = () => <Data permissions={0} ref={ref} value="111" />;
console.log(App);
ReactDOM.render(<App />, document.getElementById("root"));

是有效的,但我想做的是根据组件的类型有额外的行为

  • 例如,如果它是一个input元素并且没有编辑权限,则创建该字段readonly
  • 如果它是一个textarea元素并且没有查看权限,则创建该字段readonly
  • 如果它是一个链接并且没有查看权限,请删除它的href道具等......

这件事甚至可能吗?有没有更好的方法来解决这个问题?

4

2 回答 2

2

您应该传递如下条件属性:

<input type="text" readonly={props.value && PERMISSION_EDIT} />

所以现在,如果用户没有PERMISSION_EDIT,那么readonly就会在那里。

感谢@dfsq清理了位运算符。

于 2018-04-27T10:30:37.943 回答
0

才意识到我想错了。以不同方式处理包装的控制器不应该是 HOC 的工作。被包装的组件应该与 HOC 的“接口”兼容。

所以我做了什么:原样离开 HOC。确保我用 HOC 包装的所有组件都处理它们的 readOnly 和 disabled 道具,但没有权限知识。

如果 JS 是一种类型化语言,我也会为此创建一个接口,但现在必须这样做:)

于 2018-05-10T10:02:16.593 回答