老师您好
来源:3-12 自定义 hook 第三部分 - 正确的方式完成 URLLoader

袁门弟子
2020-06-19
老师您好,这是我定义的自定义hooks
我在第四行声明了一个useState
在第六行进行修改,
这张图是在组件中调用,
为啥我如果在第六行进行修改,会触发无限组件无限循环呢?
我如果在effect中修改,就没问题。
我是一个react初学者,我感觉是不是这样:
我以前一直以为,组件的更新,只是本组件的props和state更新才会更新,
但是在hooks中,我们的useState就等于state。我没有条件的直接修改useState,那么就会导致组件再次冲渲染,也就会导致useState再次更新(因为是无条件更新),于是就形成死循环。
所以state这种数据,必须是有条件的更新。
是这个问题嘛老师
啊啊啊 谢谢老师
====================================
老师我还有一个问题,就是effect似乎是异步的,我们可以使用async await来保证他的同步性嘛,您的代码里好像直接在effect下面return了结果, 为啥我的拿不到结果呢?崩溃
这里报错,说是unll不能个IMsg,也就是说,datas是null,看hooks:
这里应该是异步的,那么也就是return的时候datas就是null,发生setDatas之前就已经return了。
为啥老师您的代码里没有做过异步的处理,也成功了呢?
1回答
-
同学你好 你第一个问题理解是正确的 就是那个原因引发了无限循环
第二个问题 因为你的声明 data 的时候是这样写的
const [data, setData] = useState(null)
所以这个时候 data 是个 null 类型的,所以自然就会出现错误。
我原本是这样写的。
const [data, setData] = useState<any>(null)
所以就没有了这个问题,当然这样做是不好的。
你可以这样声明他的初始值
const [data, setData] = useState<null | Imsg>(null)
这样它就变成了一个 null 或者 Imsg 的联合类型,这样就可以判断当它不是 null 的时候,再使用数据就很安全了,这称之为 type guard。
甚至你可以将 useURLLoader 本身作为一个 generic function,这样你就可以使用的时候返回对应的类型。
function useURLLoader<T = {}>(url: string, deps: any[] = []) { const [data, setData] = useState<null | T>(null) }
循序渐进的修改很有意思。
132022-09-17