在仅将道具传递给孩子而不使用道具的父母中定义原型的最佳实践是什么?
简单用例:
const Parent = ({ p0, p1 }) => (
<section className="Parent">
<div>I'm the parent</div>
<p>{p0}</p>
<Child p1={p1} />
</section>
);
Parent.propTypes = {
p0: PropTypes.string.isRequired,
// p1 ?
};
和子组件:
const Child = ({ p1 }) => (
<section className="Child">
<div>I'm a Child</div>
<span>{p1}</span>
</section>
);
Child.propTypes = {
p1: PropTypes.string.isRequired,
};
这里是父母的选项:
p1: PropTypes.any.isRequired
p1: Child.propTypes.p1
(如果使用React.memo导出Child呢?)p1: PropTypes.string.isRequired
相同的类型(如果子代有10个道具,那么复制所有道具会很无聊)我理解代码的方式,即使将p1
艰难地传递给Child
,它也是Parent
实现的still部分。从逻辑上讲,Parent
中也需要它。
所以您也必须在Parent
的道具类型中定义它也是正确的。
但是我知道代码可能很乏味,但这更多的是样式问题,而不是技术上的正确性,样式容易随着范式和口味的变化而改变。因此,我想这里没有对与错的答案,只有口味。
当然,这里有一些概念您可以应用。总是有关于耦合或解耦代码的讨论,后者有时会提倡代码重复(复制道具类型)。但是,如果再次更改组件而不更改其他组件,则道具类型可能再次不同步。
我个人将从子级加载道具类型,然后将要使用的道具类型合并到父项中:
import Child from "./Child";
const Parent = ({ p0, p1 }) => {/* ... */}
const { p1 } = Child.propTypes;
Parent.propTypes = {
p0: PropTypes.string.isRequired,
p1
};
我会说这取决于道具的性质:
案例1:道具对于您的应用而言是至关重要的数据/状态
在这种情况下,我想说父母和孩子都需要道具。
案例2:孩子需要道具,但道具不是那么重要-意思是,父母也可以弥补它们
在这种情况下,我建议您不需要道具。设置道具类型并设置默认道具。
注:在任何一种情况下,对子代和父代使用相同的道具类型,以确保应用程序中的可预测性。允许父母使用任何prop类型并要求孩子使用字符串会在应用程序中造成混乱-始终最好在确定期望哪种数据类型的同时避免歧义。
第二个注意事项:如果您发现自己从父母向孩子传递了几个道具(假设父母期望10个道具,而您又向孩子传递了8个道具),则可能需要重构代码以摆脱父母,因为她可能不那么重要-但您当然是这里重要程度的法官。
第三注:谨慎使用禁用反应道具类型。这是解决问题的快速方法,但它也是创建应用程序的简便方法,在该应用程序中您不知道会流过哪些类型的数据。