Реагировать Предупреждение компонента высшего порядка - PullRequest
0 голосов
/ 21 июня 2019

Я использую HOC в реакции на ограничение доступа к компоненту, но я получаю следующее предупреждение: validateDOMNesting (...): не может отображаться как потомок. Весь код для HOC (согласно запросу) выглядит следующим образом:

import React, { Component } from 'react';
import PropTypes from 'prop-types';
import { connect } from 'react-redux';

import * as selectors from '../../store/selectors';

class AccessRestrictedComponent extends Component {
  static propTypes = {
    auth: PropTypes.object.isRequired,
    mode: PropTypes.string.isRequired,

    useWithList: PropTypes.bool,
    checkItem: PropTypes.bool,

    restrictByRole: PropTypes.bool,
    restrictByMode: PropTypes.bool,
    allowedRoles: PropTypes.array,
    allowedModes: PropTypes.array,
    children: PropTypes.node.isRequired,
  };

  static defaultProps = {
    useWithList: false,
    checkItem: null,
    restrictByRole: false,
    restrictByMode: false,
    allowedRoles: [],
    allowedModes: [],
  };

  render() {
    const { auth, mode, restrictByRole, restrictByMode, allowedRoles, allowedModes, useWithList, checkItem } = this.props;
    const { role } = auth;

    if (useWithList && !checkItem) {
      return  (React.cloneElement(this.props.children, { ...this.props }));
    }

    if (restrictByRole && restrictByMode) {
      // console.log('restricting role and mode ');
      if (allowedRoles.includes(role) && allowedModes.includes(mode)) {
        // console.log(`role: ${role} and mode: ${mode} allowed.`);
        return (React.cloneElement(this.props.children, { ...this.props }));
      } return null;
    }
    if (restrictByRole) {
      // console.log('restricting role ');
      if (allowedRoles.includes(role)) {
        // console.log(`role: ${role} allowed.`);
        return (React.cloneElement(this.props.children, { ...this.props }));
      } return null;
    }
    if (restrictByMode) {
      // console.log('restricting mode ');
      if (allowedModes.includes(mode)) {
        // console.log(`${mode} allowed.`);
        return (React.cloneElement(this.props.children, { ...this.props }));
      } return null;
    }
    // console.log('component unrestricted');
    return (React.cloneElement(this.props.children, { ...this.props }));
  }
}

const mapStateToProps = state => ({
  state,
  auth: selectors.getAuth(state),
  mode: selectors.getMode(state),
});



export default  connect(mapStateToProps)(AccessRestrictedComponent);


компонент, который я упаковываю, является стилизованным компонентом NavButton. Я использую HOC так:

<AccessRestrictedComponent restrictByRole allowedRoles={[userRoles.ADMIN]}>
  <NavButton onClick={() => this.setState({ set: true })}>
    <Icon className="material-icons md-48" color={color}>{'wallpaper'}</Icon>
  </NavButton>
</AccessRestrictedComponent>

и стилизованный компонент выглядит так:

export const NavButton = styled.button`
  display:flex;
  align-content:flex-end;
  align-self:flex-end;
  background: none;
  border: none;
  &:hover,
  &:focus{
    ${Icon}{
      cursor: pointer;
      color: ${props => props.theme.theme === themeTypes.LIGHT ? colors.SLATE_BLUE_50 : colors.lightBlue};
      border-radius: 4px;
      outline: none;
      background: linear-gradient(${colors.shuttleGrey}, ${colors.shuttleGrey}) padding-box,
                  repeating-linear-gradient(-45deg,
                    ${colors.submarine} 0, ${colors.submarine} 25%, transparent 0, transparent 50%
                  ) 0 / 8px 8px;
    }
  }
`;

Я не понимаю это предупреждение, потому что я не вкладываю кнопку, но когда я проверяю пользовательский интерфейс с помощью инструментов dev, то вкладываются две кнопки. Кто-нибудь знает, что может быть причиной этого? Это стилизованные компоненты? HOC, что-то еще может быть? Я предполагаю, что простое решение состоит в том, чтобы изменить стилизованный компонент на что-то, кроме кнопки, но я считаю, что это должен быть действительный код. В любом случае, любые предложения с благодарностью.

1 Ответ

1 голос
/ 21 июня 2019

Ошибка возникает из-за того, что при клонировании элемента вы передаете дочерние элементы клонированному дочернему элементу в качестве реквизитов.Таким образом, ваш родитель клонирует button и отправляет другую кнопку в качестве реквизита клонированной кнопке.

Исправить несложно, не отправляйте children как объединенные реквизиты.

render() {
  const { children, ...rest } = this.props;
  // ...rest
  return React.cloneElement(children, { ...rest });

  //...rest
}

Этокак вы снова не отправите children как реквизиты на children.

Примечание : вам следует заменить все ваши React.cloneElement() звонки

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...