一、useRef
useRef函数:
1.一个参数:默认值
2.返回一个固定的对象(对象的地址是不会变化的),{current: 值}
import React, { useState } from 'react'export default function App() {const inpRef = React.createRef();const [n, setN] = useState(0);return (<div><input ref={inpRef} type="text" /><button onClick={() => {console.log(inpRef.current)}}>得到input的值</button><input type="number"value={n}onChange={e => {setN(e.target.value)}} /></div>)
}
如上代码,一旦我们input出发了onChange方法,导致组件重新渲染,那么每次就会重新创建inpRef,这对我们来说是完全没有必要的呀。我们希望,一个节点,一直使用一个ref。
推荐使用使用useRef替代createRef即可。
mport React, { useState,useRef } from 'react'
window.arr =[];
export default function App() {const inpRef = useRef();window.arr.push(inpRef);const [n, setN] = useState(0);return (<div><input ref={inpRef} type="text" /><button onClick={() => {console.log(inpRef.current)}}>得到input的值</button><input type="number"value={n}onChange={e => {setN(e.target.value)}} /></div>)
}
arr中的对象都是相等的,保存的都是一个对象。
二、倒计时
同样的道理,我们每次启动的定时器应该都是同一个,而不是每次生成一个新的再清除。
最早我们是这样写的:
import React, { useState, useEffect } from 'react'
let timer = null;
export default function App() {const [n, setN] = useState(10);useEffect(() => {//useEffect中使用setTimeInterval要注意,避免循环重复的问题if(n === 0){return;}timer = setTimeout(()=>{setN(n - 1)},1000)return () => {clearTimeout(timer);}}, [n])return (<div><h1>{n}</h1></div>)
}
上面的写法有个问题就是若当App这个函数组件被引用多次时,其中一个组件销毁,就会执行clearTimeout函数,对其他的组件有影响。最好的做法是组件节点之间互不影响。
import React, { useRef, useState, useEffect } from 'react'export default function App() {const [n, setN] = useState(10);const timerRef = useRef();// 这时保存的不是元素了,可以放置任意值useEffect(() => {//useEffect中使用setTimeInterval要注意,避免循环重复的问题if(n === 0){return;}timerRef.current = setTimeout(()=>{setN(n - 1)},1000)return () => {clearTimeout(timerRef.current);}}, [n])return (<div><h1>{n}</h1></div>)
}
若setTimerInterval解决呢?
import React, { useState, useRef, useEffect } from 'react'
export default function App() {const [n, setN] = useState(10)const nRef = useRef(n); // {current:10}useEffect(() => {const timer = setInterval(() => {nRef.current--;setN(nRef.current);if(nRef.current === 0){clearInterval(timer);}}, 1000)return () => {clearInterval(timer);}}, [])return (<div><h1>{n}</h1></div>)
}
相当于实现了是跨越组件多次使用的是用一个对象。