我试图找到正确的方法来定义一些组件,这些组件可以以通用的方式使用:
<Parent>
<Child value="1">
<Child value="2">
</Parent>
当然,在父组件和子组件之间呈现有一个逻辑,您可以想象<select>和<option>是这个逻辑的一个例子。
这是为了解决这个问题的一个虚拟实现:
var Parent = React.createClass({
doSomething: function(value) {
},
render: function() {
return (<div>{this.props.children}</div>);
}
});
var Child = React.createClass({
onClick: function() {
this.props.doSomething(this.props.value); // doSomething is undefined
},
render: function() {
return (<div onClick={this.onClick}></div>);
}
});
问题是无论何时使用{this.props。Children}定义一个包装器组件,如何将某些属性传递给它的所有子组件?
从上面所有的答案中得到启发,这就是我所做的。我传递一些道具,比如一些数据和一些组件。
import React from "react";
const Parent = ({ children }) => {
const { setCheckoutData } = actions.shop;
const { Input, FieldError } = libraries.theme.components.forms;
const onSubmit = (data) => {
setCheckoutData(data);
};
const childrenWithProps = React.Children.map(
children,
(child) =>
React.cloneElement(child, {
Input: Input,
FieldError: FieldError,
onSubmit: onSubmit,
})
);
return <>{childrenWithProps}</>;
};
在我的情况下,React.cloneElement()给了我很多问题,我使用Typescript的函数组件,所以我用孩子(道具)作为一种方式来传递我的道具给我的孩子元素。同样,我的情况非常独特,我必须传递给父组件一个属性,然后基于该属性,它将某些道具传递给子组件。这可以在一个简单的CodeSandbox示例中看到
App.tsx
import "./styles.css";
import Parent from "./Parent";
export default function App() {
return (
<>
<Parent title={"With div wrapper"}>
{({ title }) => <h1>{title}</h1>}
</Parent>
<Parent>
{({ title }) => <h1>{title === undefined && "this is undefined"}</h1>}
</Parent>
</>
);
}
Parent.tsx
export interface ChildrenProps {
title?: string;
}
interface ParentWrapperProps {
children: (title: ChildrenProps) => JSX.Element;
title?: string;
}
const ParentWrapper: React.FC<ParentWrapperProps> = ({ children, title }) => {
return title ? (
<div>{children({ title: title })}</div>
) : (
<>{children({ title: undefined })}</>
);
};
export default ParentWrapper;