Как создать Компонент Высокого Порядка, который знает его детей - PullRequest
0 голосов
/ 27 апреля 2018

Я хочу создать Компонент высокого порядка , который обрабатывает то, как его дети отображаются в соответствии с переданным свойством 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 prop и т.д ...

Это вообще возможно? Есть ли лучший способ решить эту проблему?

Ответы [ 2 ]

0 голосов
/ 10 мая 2018

Просто понял, что я думал, что это неправильно. Это не должно быть задачей HOCs по-разному обрабатывать упакованные контроллеры Обернутый компонент должен быть совместим с «интерфейсом» HOC.

Итак, что я сделал: Оставил HOC как есть. Удостоверился, что все компоненты, которые я обертываю с HOC, обрабатывают их readOnly и отключили реквизиты вместо этого, но без ведома разрешения.

Если бы JS был типизированным языком, я бы тоже создал интерфейс для этого, но сейчас это нужно сделать:)

0 голосов
/ 27 апреля 2018

Вы должны передать условное свойство, как показано ниже:

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

Так что теперь, если у пользователя нет PERMISSION_EDIT, тогда будет readonly.

Спасибо @ dfsq за разъяснение о битовом операторе.

...