1.useState() 状态钩子
在react里函数式组件是没有状态的,可以使用useState()
import { useState } from 'react'
function App (){
//使用useState()
//第一个参数是变量名,第二个参数是修改变量的方法.
//useState 里面写想要的数据
const [num, setNum] = useState(0)
reutnr(
<div>
<span>{num}</span>
<div onClick={() => {setNum(val => val + 1)}}></div>
</div>
)
}
export default App
2.useContext() 共享状态钩子
父组件
import React, { useState, createContext } from 'react';
import Adiv from './useContext_divA'
import Bdiv from './useContext_divB'
//1.使用 createContext(); 并抛出让子组件引入。
export const ThemeContext = createContext();
function App() {
const [list, setlist] = useState('兄弟组件之间的值')
return (
//2.ThemeContext.Provider包裹需要数据的子组件,value:是要传过去的数据
<ThemeContext.Provider value={{ list, setlist }}>
<Adiv></Adiv>
<Bdiv></Bdiv>
</ThemeContext.Provider>
)
}
export default App
子组件1
import React, { useContext } from 'react';
import { ThemeContext } from './App.js'
function Bdiv(props) {
//3.使用useConext() 来拿到父级的数据
const theme = useContext(ThemeContext);
return (
<div>
<input
type="text"
value={theme.list}
onChange={e => theme.setlist(e.target.value)} />
</div>
)
}
export default Bdiv
子组件2
import React, { useContext } from 'react';
import { ThemeContext } from './App.js'
function Bdiv(props) {
//3.使用useConext() 来拿到父级的数据
const theme = useContext(ThemeContext);
return (
<div><input
type="text"
value={theme.list}
onChange={e => theme.setlist(e.target.value)}
/>
</div>
)
}
export default Bdiv
3.useEffect() 当react 在完成对dom操作时调用
在函数式组件中,是没有生命周期的,我们可以使用useEffect()
import React, { useState, useEffect } from 'react';
function Example() {
// 声明一个叫 “count” 的 state 变量。
const [count, setCount] = useState(0);
/* useEffect()接收两个参数,
参数一:回调函数,每次dom变化时触发。
参数二:数组,不写第二个参数时,DOM发生变化就会触发。
当传入第二个参数为空数组时,useEffect 只会在页面加载时触发一次。
当传入数组内容问count数据时,数据变化时,就会发生变化。
返回值:回调函数,当页面销毁时,或下一次useEffect触发时,就会触发返回的回调函数。
*/
useEffect(() => {
console.log('当你调用 useEffect 时,就是在告诉 React 在完成对 DOM 的更改后运行你的“副作用”函数')
return () => {
console.log('返回值是一个函数,当页面销毁或者下一次useEffect执行前执行。')
}
}, [count]);
return (
<div>
<p>You clicked {count} times</p>
<button onClick={() => setCount(count + 1)}>
Click me
</button>
</div>
);
}
export default Example
4.useReducer() 用于复杂的状态管理
类似 Redux 的功能
import React, { useReducer } from 'react'
function AppUseReducer() {
const data = { num: 1 }
const reducer = (state, action) => {
//修改数据的时候,最好和redux一样copy一份数据进行修改
switch (action.type) {
case 'add':
const a = JSON.parse(JSON.stringify(state))
return {
num: a.num + 1
}
case 'del':
return {
...state,
num: state.num - 1
}
default:
return state
}
}
/*
创建一个useReducer()
参数一:回调函数,接收两个参数
参数一:state 数据
参数二:action 修改的类型
参数二:数据
生成了data 里面的数据,dispatch 用于修改数据的方法
*/
const [data, dispatch] = useReducer(reducer, data)
// 结构赋值
const { num } = state
return (
<div>
<span>{num}</span>
<button onClick={() => { dispatch({ type: 'add' }) }}>增加</button>
<button onClick={() => { dispatch({ type: 'del' }) }}>减少</button>
</div>
)
}
export default AppUseReducer
5.useCallback() useMemo() useRef()
1.每次更新的时候函数式里面所有的东西都要更新,我们定义的方法,都要执行一遍。
但是我们的方法只需要在函数调用的时候执行一次,就可以了,后续更新我不想让他在创建一遍。
可以用 useCallback() 和 useMemo() 来进行缓存,让react每次走缓存里面的方法。
useRef() 它可以用来获取组件实例对象或者是DOM对象。
还可以用于保存数据,比如定时器,这样便可以在多次渲染之后依旧保存定时器ID,从而能正常清除定时器。
import react, { useState, useRef, useCallback, useMemo } from 'react'
const App = () => {
const [num, setConst] = useState(0)
const time = useRef()
const add = useCallback(() => {
if (!time.current)
time.current = setInterval(() => {
setConst(num => num + 1)
}, 1000)
}, [])
//useCallback() 接收两个参数
//参数一: 回调函数。
//参数二: 数组,当数组为空时,第一次创建组件是执行,后续不在进行执行
//当数组传入数据时,数据变化时,执行。
const del = useCallback(() => {
clearInterval(time.current)
time.current = null
}, [])
// useMemo() 接收两个参数
// 参数一: 回调函数,return出的东西进行缓存。
// 参数二: 数组,当数组为空时,第一次创建组件是执行,后续不在进行执行
//当数组传入数据时,数据变化时,执行。
const reset = useMemo(() => {
return () => {
del()
setConst(0)
}
}, [])
return (
<div>
<div>{num}</div>
<div className='clickButtom'>
<button onClick={add}>启动</button>
<button onClick={del}>暂停</button>
<button onClick={reset}>重置</button>
</div>
</div>
)
}
export default App