我个人建议传递上下文:我相信这将使自定义钩子更清晰、更灵活、更可测试。它将对上下文数据进行操作的逻辑与负责获取该数据的逻辑分离。
Clarity
如果你使用useContext
在自定义钩子内部,这成为钩子的隐式契约:通过查看调用签名并不清楚它依赖于上下文中的值。一般来说,显式数据流比隐式数据流更好。 (当然,Context API 的存在是因为有时隐式数据流很有用,但大多数情况下我认为显式更好)
灵活性
您可能在某个时候发现一个组件需要利用自定义挂钩中包含的逻辑,但需要提供与上下文不同的值,或者可能想要修改该值。在这种情况下,这样做会非常方便:
const MySpecialCaseComponent = () => {
const context = useContext(MyContext);
useMyCustomHook({
...context,
propToOverride: someValue
});
return (<div></div>)
}
如果自定义挂钩直接从上下文读取,那就非常不方便 - 您可能必须引入一个包装在新上下文提供程序中的新组件。
可测试性
如果自定义挂钩不依赖于上下文 API,则测试它会更容易。也许在最简单的情况下,您只需使用测试数据调用自定义挂钩并检查返回值即可。
或者你可以编写一个测试,例如:
test("Test my custom hook", () => {
const TestComponent = () => {
useMyCustomHook({ /** test data */ });
return (/* ... */);
};
const element = shallow(<TestComponent />);
// do testing here
})
如果您在挂钩中使用上下文,那么您必须在<MyContext>
供应商,这让事情变得更加复杂。尤其如果您尝试进行浅渲染(如果您使用的是react-test-renderer/shallow
, 使用上下文测试组件更加复杂 https://stackoverflow.com/a/55013256/79247.
TL;DR我不认为这是wrong to useContext
在自定义挂钩内,但我认为显式数据流应该是您的首选,出于所有常见原因,显式数据流通常优于隐式数据流。