【发布时间】:2019-05-03 14:48:59
【问题描述】:
我第一次尝试 React 钩子,一切似乎都很好,直到我意识到当我获取数据并更新两个不同的状态变量(数据和加载标志)时,我的组件(数据表)被渲染了两次,甚至尽管对状态更新程序的两次调用都发生在同一个函数中。这是我的 api 函数,它将两个变量都返回给我的组件。
const getData = url => {
const [data, setData] = useState(null);
const [loading, setLoading] = useState(true);
useEffect(async () => {
const test = await api.get('/people')
if(test.ok){
setLoading(false);
setData(test.data.results);
}
}, []);
return { data, loading };
};
在普通类组件中,您只需调用一次即可更新可能是复杂对象的状态,但“挂钩方式”似乎是将状态拆分为更小的单元,其副作用似乎是单独更新时多次重新渲染。有什么办法可以缓解这种情况吗?
【问题讨论】:
-
如果你有依赖状态,你应该使用
useReducer -
哇!我只是刚刚发现了这一点,它完全颠覆了我对反应渲染如何工作的理解。我无法理解以这种方式工作的任何优势 - 异步回调中的行为与普通事件处理程序中的行为不同似乎相当随意。顺便说一句,在我的测试中,似乎只有在处理完所有 setState 调用之后才会进行协调(即更新真实 DOM),因此无论如何都浪费了中间渲染调用。
-
“异步回调中的行为与普通事件处理程序中的行为不同,这似乎相当随意” - 这不是随意的,而是通过实现 [1]。 React 批处理在 React 事件处理程序期间完成的所有 setState 调用,并在退出其自己的浏览器事件处理程序之前应用它们。但是,事件处理程序之外的几个 setState(例如在网络响应中)将不会被批处理。所以在这种情况下你会得到两次重新渲染。 [1]github.com/facebook/react/issues/10231#issuecomment-316644950
-
'但“钩子方式”似乎是将状态拆分为更小的单元'——这有点误导,因为只有在调用
setX函数时才会发生多次重新渲染在异步回调中。来源:github.com/facebook/react/issues/14259#issuecomment-439632622、blog.logrocket.com/…
标签: javascript reactjs react-hooks