gpt4 book ai didi

reactjs - React TS - 如何将 props 从父组件传递给深度嵌套的子组件

转载 作者:行者123 更新时间:2023-12-04 04:17:43 24 4
gpt4 key购买 nike

目前,我已经创建了一些不同的表单元素。我正在尝试以不同的方式创建它们,这样我就可以将它们拼凑在一起,为一个表单创建不同的格式。

这是我的一些表单元素:

// Field Component
interface IField extends ILabel {}

export const Field: React.FunctionComponent<IField> = props => {
return (
<div>
<Label {...props} />
{props.children}
</div>
);
};

// Label Component
interface ILabel {
htmlFor: string;
label: string;
required?: boolean;
}

export const Label: React.FunctionComponent<ILabel> = props => {
return (
<label htmlFor={props.htmlFor}>
{props.label}
// Some required icon would go where I've added the <span />.
{props.required && <span />}
</label>
);
};

// Input Wrapper Component
export const InputWrapper: React.FunctionComponent = props => {
return <div>{props.children}</div>;
};

// Input Component
interface IInput {
type: string;
id: string;
name: string;
value?: string;
placeholder?: string;
required?: boolean;
}

export const Input: React.FunctionComponent<IInput> = props => {
return (
<input
type={props.type}
id={props.id}
name={props.name}
value={props.value}
placeholder={props.placeholder}
required={props.required}
/>
);
};

下面是我实现组件的方式:

<Field htmlFor="name" label="Name:" required>
<InputWrapper>
<Input
id="name"
type="text"
name="name"
placeholder="Enter your name..."
/>
</InputWrapper>
</Field>

我希望能够在 Field 组件上设置 required Prop ,它也会被传递到我的 Input 组件,无论它嵌套得有多深。这怎么可能?

我还提供了一个 CodeSandBox 演示。

提前感谢您的帮助!

最佳答案

当使用 props.children 并且不可能知道嵌套组件的确切层次结构,或者它可能因不同的用例而异,可能很难尝试通过props 从 parent 到 child 。

Context为组件树提供一种共享数据和对更改使用react的方法。

Your codesandbox adapted to the explained solution
https://codesandbox.io/s/react-stackoverflow-60241936-fvkdo

在您的情况下,您需要为 Field 组件创建一个 Context 以“共享”required 字段并定义一个默认值值(value)。

interface IFieldContext {
required?: boolean;
}

export const FieldContext = React.createContext<IFieldContext>({
required: false // default value when the prop is not provided
});

然后在 Field 组件中使用 FieldContext.Provider,您可以为嵌套组件分配“共享”值。

export const Field: React.FunctionComponent<IField> = props => {
return (
<FieldContext.Provider value={{ required: props.required }}>
<Label {...props} />
{props.children}
</FieldContext.Provider>
);
};

最后,在 Input 组件中,使用 FieldContext.Consumer 访问“共享”值并检索分配给字段 组件。然后您将能够从 IInput 接口(interface)中删除 required 字段,因为它现在来自 Context 而不是 props 了。

interface IInput {
type: string;
id: string;
name: string;
value?: string;
placeholder?: string;
}

export const Input: React.FunctionComponent<IInput> = props => {
return (
<FieldContext.Consumer>
{context => (
<input
type={props.type}
id={props.id}
name={props.name}
value={props.value}
placeholder={props.placeholder}
required={context.required} // access context prop
/>
)}
</FieldContext.Consumer>
);
};

“瞧”,你可以在 Field 组件上使用 required Prop ,它将应用于你嵌套的 Input 组件,无论 Input 的嵌套有多深...花哨的东西😄

export const App: React.FunctionComponent = () => {
return (
<Field htmlFor="name" label="Name:" required>
<InputWrapper>
<Input
id="name"
type="text"
name="name"
placeholder="Enter your name..."
/>
</InputWrapper>
</Field>
);
};

关于reactjs - React TS - 如何将 props 从父组件传递给深度嵌套的子组件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/60241936/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com