Проптипы дочерних компонентов типа не работают

Я пытаюсь указать конкретный класс компонента с типом Input, но это дает мне предупреждение.

Warning: Failed prop type: Invalid prop children supplied to MyComponent.

MyComponent.js

    import React, { Component, cloneElement } from 'react';
    import Input from '../Input';

    class MyComponent extends Component {
      static propTypes = {
        children: PropTypes.oneOfType([
          PropTypes.shape({
            type: PropTypes.oneOf([Input]),
          }),
          PropTypes.arrayOf(
            PropTypes.shape({
              type: PropTypes.oneOf([Input]),
            })
          ),
        ]).isRequired,
      }

      renderChildren(child) {
        const clone = cloneElement(child, {newProp: 'blaaa'});
        return <div className='inner'>{clone}</div>;
      }

      render() {
        const { children } = this.props;
        return (
          <div>
            {React.Children.map(children, this.renderChildren)}
          </div>
        );
      }
    }

export default MyComponent;

Мой входной компонент урезан.

import React, { Fragment } from 'react';

const Input = ({name}) => (
    <Fragment>
      <input
      />
    </Fragment>
);

export default Input;

Консольный журнал для детей:

$$typeof: Symbol(react.element)
key: null
props: {id: "email", placeholder: "email", type: "tel", name: "Email", styles: Array(1), …}
ref: null
type: ƒ Input(_ref)
_owner: FiberNode {tag: 1, key: "inputname", type: ƒ, stateNode: null, return: FiberNode, …}
_self: null
__proto__: Object

Можете ли вы предоставить console.info(this.props.children) во всех его вариантах / вариантах использования.

Matt Carlotta 18.11.2018 22:54

Просто добавил журнал консоли в мой отредактированный пост выше внизу поста.

me-me 18.11.2018 23:00
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Навигация по приложениям React: Исчерпывающее руководство по React Router
Навигация по приложениям React: Исчерпывающее руководство по React Router
React Router стала незаменимой библиотекой для создания одностраничных приложений с навигацией в React. В этой статье блога мы подробно рассмотрим...
Массив зависимостей в React
Массив зависимостей в React
Все о массиве Dependency и его связи с useEffect.
0
2
1 555
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Это предполагает, что ваш MyComponent будет последовательно получать один или несколько React Input.

Рабочий пример: https://codesandbox.io/s/045kw2pq30

компонент / NonInput.js

import React, { Fragment } from "react";
import PropTypes from "prop-types";

const NonInput = props => (
  <code>
    <pre>{JSON.stringify(props, null, 4)}</pre>
  </code>
);

NonInput.propTypes = {
  props: PropTypes.objectOf(PropTypes.string)
};

export default NonInput;

компоненты / Input.js

import React, { Fragment } from "react";
import PropTypes from "prop-types";

const Input = ({ newProp, ...props }) => (
  <Fragment>
    {console.info(newProp)}
    <input className = "uk-input" {...props} />
  </Fragment>
);

Input.propTypes = {
  newProp: PropTypes.string,
  props: PropTypes.objectOf(PropTypes.string)
};

export default Input;

компоненты / MyComponent.js

import React, { PureComponent, cloneElement } from "react";
import PropTypes from "prop-types";
import Input from "./Input";

const shapeOfChildren = PropTypes.shape({
  type: PropTypes.oneOf([Input]).isRequired,
  props: PropTypes.shape({
    name: PropTypes.string.isRequired,
    type: PropTypes.string.isRequired,
    placeholder: PropTypes.string.isRequired
  }).isRequired
});

class MyComponent extends PureComponent {
  renderChildren = child => (
    <div className = "inner">{cloneElement(child, { newProp: "blaaa" })}</div>
  );

  render = () => (
    <div className = "uk-form-large">
      {React.Children.map(this.props.children, this.renderChildren)}
    </div>
  );
}

MyComponent.propTypes = {
  children: PropTypes.oneOfType([
    shapeOfChildren,
    PropTypes.arrayOf(shapeOfChildren)
  ]).isRequired
};

export default MyComponent;

компоненты / Example.js (удалите NonInput, сохраните, затем обновите страницу, чтобы удалить предупреждение PropType - если вы хотите, чтобы оно отображало более определенное предупреждение, напишите настраиваемая функция валидатора (пример внизу))

import React from "react";
import MyComponent from "./MyComponent";
import Input from "./Input";
import NonInput from "./NonInput";

export default () => (
  <MyComponent>
    <Input name = "firstName" type = "text" placeholder = "First Name" />
    <Input name = "lastName" type = "text" placeholder = "Last Name" />
    <NonInput name = "lastName" type = "text" placeholder = "Last Name" />
  </MyComponent>
);

Спасибо, Мэтт, но узел подразумевает, что все может быть отрисовано как дочерний элемент: числа, строки, элементы или массив (или фрагмент). Я не хочу, чтобы что-то рендерилось. Я специально хочу, чтобы компонент Input был дочерним для рендеринга.

me-me 18.11.2018 23:48

В этом случае замените node на Input от shape.

Matt Carlotta 18.11.2018 23:51

Но это то, что у меня есть в моем примере, и я получаю предупреждение? Можете ли вы привести пример формы ввода, которая отличается от моей?

me-me 18.11.2018 23:55

PropTypes.shape ({тип: PropTypes.oneOf ([Вход]),})

me-me 18.11.2018 23:59

Я сейчас не сижу за своим компьютером, но в основном вы должны скопировать структуру того, что вы предоставили выше, в console.info(this.props.children).

Matt Carlotta 19.11.2018 00:00

Правильно, и в моем посте это есть. тип: ƒ Вход (_ref)

me-me 19.11.2018 00:58

тип: PropTypes.oneOf ([Вход]),

me-me 19.11.2018 00:59

Обновленный ответ.

Matt Carlotta 19.11.2018 02:37

Кстати, вы можете пропустить эту лишнюю проверку. Поскольку вы ожидаете, что он всегда будет компонентом Input, нет необходимости передавать его как дочерний. Вместо этого просто передайте props в MyComponent и добавьте / клонируйте их в Input. В этом было бы больше смысла, и с ним было бы легче проверить.

Matt Carlotta 19.11.2018 02:48

Спасибо за полный пример.

me-me 19.11.2018 03:21

Другие вопросы по теме