useState:
const [toDos, setToDos] = useState('');
// 返回一个数组,数组里面这个state的值和更新state值的函数
useEffect:
useEffect(() => {
window.localStorage.setItem('toDos', JSON.stringify(toDos))
}, [toDos])
// 副作用每次状态更新都会执行,指定第二个参数后只有指定依赖更新才会执行副作用,如果参数是个空数组,则只会执行第一次更新,效果类似componentDidMount
// 注意:useEffect是在数据更新后视图渲染完毕执行的,而且多个useEffect编写时是按写的代码位置顺序执行的从下往下执行
useRef,useLayoutRef:
const inputRef = useRef(null);
// 这个钩子就是等节点渲染完成之后执行,类似于vue的mounted,第二个参数是依赖项,返回值就是节点销毁时执行的回调函数
useLayoutEffect(()=>{
// 节点渲染完成才聚焦
inputRef.current.focus();
},[])
// inputRef.current就可以拿到DOM
console.log(inputRef.current)
<input type="text" ref={inputRef}/>
Provider和Consumer实现跨多层组件通信:
const UserContext = createContext();
// 顶层组件:
<UserContext.Provider value={{ name: 'Susuk' }}></UserContext.Provider>
// 子组件取值:使用render-props模式,data的值就是value传的数据
<UserContext.Consumer>{(data)=><div>{data.name}</div>}</UserContext.Consumer>
useContext:
const context = createContext(/*如果是tsx那这里需要写默认值,provider那没写value默认就用这个值*/);
// 参数就是context对象
const value = useContext(context);
// 这个value就是在Provider上写的value的值:
<Provider value={值}></Provider>
// 一般使用的时候会将context对象抽离到一个文件中导出使用
useContext和Provider-Consumer区别:
useContext是在js中获取值,后者是在jsx中获取值
useReducer:
import { useReducer } from 'react'
interface Action {
type?: string
payload?: any
}
// 抽取的reducer,use的时候调用,并且将初始state传入,调用的时候还可以传入payload
const reducer = (state: number, action: Action) => {
switch (action.type) {
case 'increment':
return state + 1 + action.payload;
case 'decrement':
return state - 1;
default:
return state
}
}
function SubComponent() {
let initialState = 0
// 返回初始state和调用对应逻辑的函数,调用dispatch执行对应逻辑时传入对应的type即可
const [state, dispatch] = useReducer(reducer, initialState)
return <div>
<h3>{state}</h3>
<button onClick={() => dispatch({ type: 'increment',payload:2 })}>+1</button>
<button onClick={() => dispatch({ type: 'decrement' })}>-1</button>
</div>
}