У меня есть простой составной компонент с кучей статических подкомпонентов:
// @flow
import React, { Component, Children } from 'react';
type Props = {
children: React.ChildrenArray<React.Node> | React.Node,
}
class Toggle extends Component<Props> {
static On = props => (props.on ? props.children : null);
static Off = props => (props.on ? null : props.children);
static Button = props => (
<button
onClick = {props.toggle}
type = "button"
style = {{ display: 'inline-block' }}
>
<pre>{JSON.stringify(props.on, null, 2)}</pre>
</button>
);
state = { on: false }
toggle = () => {
this.setState(
({ on }) => ({ on: !on }),
// maybe this.props.someCallback
() => console.info(this.state.on),
);
}
render() {
return Children.map(
this.props.children,
childElem => React.cloneElement(childElem, {
on: this.state.on,
toggle: this.toggle,
}),
);
}
}
export default Toggle;
Предупреждение появляется, когда я пытаюсь поместить некоторые другие элементы в область Toggle children. Например:
<Toggle>
<Toggle.On>On</Toggle.On>
<span /> <-- this is savage
<Toggle.Button />
<Toggle.Off>Off</Toggle.Off>
</Toggle>
Все работает, но мой тип потока предупреждает меня об этом интервале следующим образом:
Warning: Received `false` for a non-boolean attribute `on`.....
Warning: Invalid value for prop `toggle` on <span> tag....
Как я могу усмирить эту противную девушку?
Да, конечно, но как я могу обработать это предупреждение? Мне, возможно, понадобятся какие-то другие теги внутри моего составного элемента, но все они вызовут это предупреждение.
Просто сделай это? Статический on = props => (props.on? True: null)? Что вы пытаетесь сделать, присваивая дочерним элементам логическое значение?
Извините, код не закончился. Детей нужно назначить отдельно.



![Безумие обратных вызовов в javascript [JS]](https://i.imgur.com/WsjO6zJb.png)


Спасибо, ребята, я думаю, правильное решение - просто проверить, правильный ли тип смонтированного узла, в противном случае - просто клонировать узел с обычными реквизитами узла:
// @flow
import React, { Component, Children } from 'react';
type Props = {
children: React.ChildrenArray<React.Node> | React.Node,
}
class Toggle extends Component<Props> {
static On = props => (props.on ? props.children : null);
static Off = props => (props.on ? null : props.children);
static Button = props => (
<button
onClick = {props.toggle}
type = "button"
style = {{ display: 'inline-block' }}
>
<pre>{JSON.stringify(props.on, null, 2)}</pre>
</button>
);
state = { on: false }
toggle = () => {
this.setState(
({ on }) => ({ on: !on }),
// maybe this.props.someCallback
() => console.info(this.state.on),
);
}
// Checking here
allowedTypes = ({ type }) => {
return [
(<Toggle.On />).type,
(<Toggle.Off />).type,
(<Toggle.Button />).type,
].includes(type);
}
render() {
return Children.map(
this.props.children,
(childElem) => {
const elemProps = this.allowedTypes(childElem) ? {
on: this.state.on,
toggle: this.toggle,
} : childElem.props;
return React.cloneElement(childElem, elemProps);
},
);
}
}
export default Toggle;
Вы также можете сделать это, просто поместив компоненты в список и проверив их тип внутри .map, добавив настраиваемые реквизиты или иным образом просто вернув исходный дочерний элемент.
const allowedTypes = [ToggleOn, ToggleOff, ToggleButton]
return React.Children.map(props.children, child => {
if (allowedTypes.includes(child.type)) {
return React.cloneElement(child, {on, toggle})
}
return child
})
}
Я думаю, что props.children включает тег <span />, поэтому вы получаете это предупреждение.