根据我的经验,props
像这样传递未记忆的函数并不常见。
// don't do this
<Wrapper
getWebsites={() => fetchJson('websites').then(setWebsites)}
loadUserRatings={() => fetchJson('ratings').then(setUserRatings)}
/>
如果它们被正确记忆(使用类似 的钩子useCallback()
,或通过在任何组件之外定义),那么将它们传递给deps
你的 是安全的,useEffect()
而不会产生任何行为差异。这是修复上述情况的示例。*
// do this
const fetchJson = (...args) => fetch(...args).then(res => res.json());
const Parent = () => {
const [websites, setWebsites] = useState([]);
const [userRatings, setUserRatings] = useState({});
// useCallback creates a memoized reference
const getWebsites = useCallback(
() => fetchJson('websites').then(setWebsites),
[setWebsites]
);
const loadUserRatings = useCallback(
() => fetchJson('ratings').then(setUserRatings),
[setUserRatings]
);
...
<Wrapper
getWebsites={getWebsites}
loadUserRatings={loadUserRatings}
/>
* useState()
memoizes在其返回值的调度功能,因此从技术上讲是安全的通过[]
为deps
每一个useCallback()
在这里,但我相信,指定调度功能的依赖有助于明确地传达了作者的意图更加清晰,而且也没有缺点传球他们。
Ramesh 的回答足以应对这种情况。
如果您发现自己遇到了第一种情况,那么作为最后的手段,您可以props
像这样初始化组件的状态。
const Wrapper = (props) => {
const [{ getWebsites, loadUserRatings }] = useState(props);
useEffect(() => {
getWebsites();
loadUserRatings();
}, [getWebsites, loadUserRatings]);
return (
<>
<Header />
<Websites />
<Sync />
</>
);
};