一、useState
注意事项:
1.setState的方法并不像函数式组件会自动合并,所以需要我们通过展开运算符手动合并。
// 更新方式1:展开运算符// const info={...userInfo,...data}// setUserInfo(info)// 方式2:setUserInfo(Object.assign({},userInfo))
2.setState中的更新并不能拿到最新的值,如果需要可以通过在useEffect中获取更新后的值。
但是这里也会有一个问题就是如果setState更新的动作也是在useEffect中操作,那可能也还是拿不到,可能就需要根据具体业务场景解决。
3.更新不及时的问题:
解决方式式通过函数式的方式进行赋值更新。函数体内可以实现想要的代码逻辑赋值,比如加两次等。
const oddAdd=()=>{// 问题:只会加一次// setCount(count+1)// setCount(count+1)// 解决:setCount (()=>{return count+1});}
4.useState严禁出现在代码块内,最好写到函数的起始位置方便阅读。
5.实现强制刷新。只需要给useState重新赋一次值即可。
const [,forceUpdate]=useState({})const onRefresh=()=>{forceUpdate({})}return (<div className="App"><header className="App-header"><button onClick={onRefresh}>点我强制刷新</button></header></div>)
6.异步更改,多个状态的更改会合并,如果不能信任之前的状态,应该使用回调函数的方式改变状态。
二、useRef
作用:1.获取子组件或dom节点的实例对象;
import React,{useRef} from "react";
function App(){const inputRef=useRef(null)const onButtonClick=()=>{if(inputRef){inputRef.current.focus()}}return (<div className="App"><input type="text" ref={inputRef} /><button onClick={onButtonClick}>点击获得焦点</button></div>)
}
export default App;
2.存储渲染周期之间的共享数据
利用useRef获取上一轮的props或状态
import React,{useState,useRef, useEffect} from "react";
function App(){const [count,setCount]=useState(0);// 定义一个ref实例对象const prevCountRef=useRef();// 将prevCountRef实例对象的值赋值给常量prevCountconst prevCount=prevCountRef.current// useEffect中将任意元素中的值等于count的元素绑定为prevCountRef对象useEffect(()=>{(prevCountRef as any).current=count})return (<div className="App"><h1>现在的值:{count};之前的值:{prevCount}</h1><button onClick={()=>setCount((count=>count+1))}>增加</button></div>)}
export default App;
定时器存入useRef中,定时可id可以在整个组件内使用。(不知道怎么用的其实,没有明白使用场景)
import React,{useState,useRef, useEffect} from "react";
function App(){const intervalRel=useRef('')useEffect(()=>{const id=setInterval(() => {}, 500);intervalRel.current=idconsole.log(intervalRel)return ()=>{clearInterval(intervalRel.current)}})return (<div className="App"><h2>111</h2></div>)}
export default App;
useRef使用注意事项:
1、useRef的每次渲染,返回值都不变
2.ref.current发生拜年话并不会造成重新渲染
3.不可以在render里面更新ref.current的值
4.ref.current的值不可作为其他hooks的依赖项,因为ref是可变的,不会使页面再次渲染,react不会跟踪ref的变化。
5.不要在render函数中更新ref.current的值
三、forwardRef
需求:父组件中获取某个子组件中的input元素,然后设置使input获取焦点。
import React,{useState,useRef,forwardRef, useEffect} from "react";
// 子组件
const Child=forwardRef((props,ref)=>{console.log('props.ref==>',ref)return <><input type="text" placeholder={props.placeholder} ref={ref}/></>
})
// 父组件
function App(){const ref=useRef(null)const [placeholder,setPlaceHolder]=useState('请输入搜索内容')const onClick=()=>{console.log('获取到的子组件内容',ref.current.value)ref.current.focus()}return (<div className="App"><Child ref={ref} placeholder={placeholder}></Child><button onClick={onClick}>获取子组件内容</button></div>)}
export default App;