在 ReactJS 中使用父 Prop 的子组件

Child Component Making Use of Parents' Prop in ReactJS

我正在创建一个表单组件,它将包含一个 Form 组件和一个 Input 组件。像这样:

<Form>
  <Input name="name" />
  <Input name="email" />
</Form>

在我的设置中,标签是从 name 属性自动生成的。不过,我想做的是提供一个不显示标签的选项。现在,我可以像这样在每个 <Input> 组件上执行此操作:

<Form>
  <Input noLabel name="name" />
  <Input noLabel name="email" />
</Form>

但我真正想做的是将它添加到 <Form> 组件并让它自动应用于每个 <Input> 组件。像这样:

<Form noLabel>
  <Input name="name" />
  <Input name="email" />
</Form>

我设想的方式是,在定义我的 <Input> 组件时,我可以检查是否在 <Form> 组件上设置了 noLabel 道具。像这样:

export const Input = props => {
  ...
  {!props.noLabel && <label>...}
  <input.../>
  ...
}

但我不知道如何从 <Form> 组件访问 noLabel 道具,以便我可以检查它是否已设置。

关于如何做到这一点有什么想法吗?

在您的 Form 组件中,您可以使用 React.ChildrenReact.cloneElementnoLabel 属性传递给输入组件,如下所示:

const children = React.Children.map(this.props.children, child =>
  React.cloneElement(child, { noLabel: this.props.noLabel  })
);

return (<form>{children}</form>);

一种方法是操纵 formchildren。映射每个并注入 noLabel prop。您仍然需要检查 Input 内部是否有 noLabel prop,但工作量肯定会减少

const Form = ({children, noLabel}) =>{
    return React.children.forEach(_, child =>{
        return React.cloneElement(child, { noLabel })
    })
} 

我会选择上下文方法,以克服我在对 Mohamed 的解决方案的评论中提到的问题,这也将启用间接嵌套:

const FormContext = React.createContext();

const Form = ...;

Form.Context = FormContext; // or simply Form.Context = React.createContext();

export default ({noLabel, ...props}) => <FormContext.Provider value={{noLabel}}/>;

然后您的输入组件将像这样使用它:

const Input = props => {
  const {noLabel} = useContext(Form.Context);

  return (... < your no label logic here > ...);
}

或者像这样:

const Input = ....;

export default props => () => {
  const {noLabel} = useContext(Form.Context);

  return <Input noLabel={noLabel}/>
}