文章目录
- 1、Hook
- 1.1 为什么会出现hook
- 1.2 useState
- 1.3 useEffect
- 1.4 useContext
- 1.5 useReducer
- 1.6 useCallback
- 1.7 useMemo
- 1.8 useRef
- 1.8.1 ref绑定dom
- 1.8.2 ref解决闭包缺陷
- 1.9 useImperativeHandle
- 1.10 useLayoutEffect
- 1.11 自定义Hook
- 1.11.1 什么是自定义Hook
- 1.11.2 Context的共享
- 1.11.3 获取鼠标滚动位置
- 1.11.4 storage
- 1.12 redux中的hook
- 1.13 讲讲SPA和 Hydration
- 1.14 useId
- 1.15 useTransition
- 1.16 useDeferredValue
1、Hook
1.1 为什么会出现hook
1.2 useState
import React, { memo, useState } from "react";
const App = memo(() => {
const [message, setMessage] = useState("Hello World");
const [count, setCount] = useState(100);
const [banners, setBanners] = useState([]);
function changeMessage() {
setMessage("你好啊, 李银河!");
}
return (
<div>
<h2>App: {message}</h2>
<button onClick={changeMessage}>修改文本</button>
</div>
);
});
export default App;
1.3 useEffect
import React, { memo, useEffect } from 'react'
import { useState } from 'react'
const App = memo(() => {
const [count, setCount] = useState(0)
useEffect(() => {
console.log("监听redux中数据变化, 监听eventBus中的why事件")
return () => {
console.log("取消监听redux中数据变化, 取消监听eventBus中的why事件")
}
})
return (
<div>
<button onClick={e => setCount(count+1)}>+1({count})</button>
</div>
)
})
export default App
import React, { memo, useEffect } from 'react'
import { useState } from 'react'
const App = memo(() => {
const [count, setCount] = useState(0)
useEffect(() => {
console.log("修改title")
})
useEffect(() => {
console.log("监听redux中的数据")
return () => {
}
})
useEffect(() => {
console.log("监听eventBus的why事件")
return () => {
}
})
return (
<div>
<button onClick={e => setCount(count+1)}>+1({count})</button>
</div>
)
})
export default App
import React, { memo, useEffect } from "react";
import { useState } from "react";
const App = memo(() => {
const [count, setCount] = useState(0);
const [message, setMessage] = useState("Hello World");
useEffect(() => {
console.log("修改title:", count);
}, [count]);
useEffect(() => {
console.log("发送网络请求, 从服务器获取数据");
return () => {
console.log("会在组件被卸载时, 才会执行一次");
};
}, []);
return (
<div>
<button onClick={(e) => setCount(count + 1)}>+1({count})</button>
<button onClick={(e) => setMessage("你好啊")}>
修改message({message})
</button>
</div>
);
});
export default App;
1.4 useContext
import { createContext } from "react";
const UserContext = createContext();
const ThemeContext = createContext();
export { UserContext, ThemeContext };
import React, { memo, useContext } from 'react'
import { UserContext, ThemeContext } from "./context"
const App = memo(() => {
const user = useContext(UserContext)
const theme = useContext(ThemeContext)
return (
<div>
<h2>User: {user.name}-{user.level}</h2>
<h2 style={{color: theme.color, fontSize: theme.size}}>Theme</h2>
</div>
)
})
export default App
const root = ReactDOM.createRoot(document.getElementById('root'));
root.render(
<UserContext.Provider value={{name: "why", level: 99}}>
<TokenContext.Provider value={'coderwhy'}>
<App />
</TokenContext.Provider>
</UserContext.Provider>
);
1.5 useReducer
import React, { memo, useReducer } from 'react'
function reducer(state, action) {
switch(action.type) {
case "increment":
return { ...state, counter: state.counter + 1 }
case "decrement":
return { ...state, counter: state.counter - 1 }
case "add_number":
return { ...state, counter: state.counter + action.num }
case "sub_number":
return { ...state, counter: state.counter - action.num }
default:
return state
}
}
const App = memo(() => {
const [state, dispatch] = useReducer(reducer, { counter: 0, friends: [], user: {} })
return (
<div>
{}
<h2>当前计数: {state.counter}</h2>
<button onClick={e => dispatch({type: "increment"})}>+1</button>
<button onClick={e => dispatch({type: "decrement"})}>-1</button>
<button onClick={e => dispatch({type: "add_number", num: 5})}>+5</button>
<button onClick={e => dispatch({type: "sub_number", num: 5})}>-5</button>
<button onClick={e => dispatch({type: "add_number", num: 100})}>+100</button>
</div>
)
})
export default App
1.6 useCallback
import React, { memo, useState, useCallback, useRef } from "react";
const HYHome = memo(function (props) {
const { increment } = props;
console.log("HYHome被渲染");
return (
<div>
<button onClick={increment}>increment+1</button>
{}
</div>
);
});
const App = memo(function () {
const [count, setCount] = useState(0);
const [message, setMessage] = useState("hello");
console.log("App组件被重新渲染");
const countRef = useRef();
countRef.current = count;
const increment = useCallback(function foo() {
console.log("increment");
setCount(countRef.current + 1);
}, []);
return (
<div>
<h2>计数: {count}</h2>
<button onClick={increment}>+1</button>
<HYHome increment={increment} />
<h2>message:{message}</h2>
<button onClick={(e) => setMessage(Math.random())}>修改message</button>
</div>
);
});
export default App;
1.7 useMemo
import React, { memo, useCallback } from "react";
import { useMemo, useState } from "react";
const HelloWorld = memo(function (props) {
console.log("HelloWorld被渲染~");
return <h2>Hello World</h2>;
});
function calcNumTotal(num) {
let total = 0;
for (let i = 1; i <= num; i++) {
total += i;
}
return total;
}
const App = memo(() => {
const [count, setCount] = useState(0);
const result = useMemo(() => {
return calcNumTotal(50);
}, []);
function fn() {}
const info = useMemo(() => ({ name: "why", age: 18 }), []);
return (
<div>
<h2>计算结果: {result}</h2>
<h2>计数器: {count}</h2>
<button onClick={(e) => setCount(count + 1)}>+1</button>
<HelloWorld result={result} info={info} />
</div>
);
});
export default App;
1.8 useRef
1.8.1 ref绑定dom
import React, { memo, useRef } from 'react'
const App = memo(() => {
const titleRef = useRef()
const inputRef = useRef()
function showTitleDom() {
console.log(titleRef.current