- useState - useEffect - useContext - useReducer - useMemo - useCallback - useRef - 自定义hook
npm install lanyage-react-hooks-demo``jsx`
const [count, setCount] = useState({
firstCount: initialCount1,
secondCount: initialCount2
});
`jsxcount ${count}
// 操作DOM
useEffect(() => {
console.log("use effect.");
document.title = ;
}, [count]);
// 根据userId的变化来执行这个操作
const [useId, setUserId] = useState(1001);
useEffect(() => {
// fetch, ajax, axios
}, [userId])
`
`jsx
// producer
// App.jsx
export const XXXContext = React.createContext();
// consumer
import {useContext} from 'react';
import {XXXContext} from 'App';
const xxx = useContext(XXXContext);
`
`jsx
import {useReducer, useContext} from 'react';
const initialState = 0;
const reducer = (state, action) => {
switch(action.type) {
case "increment":
return state + 1;
default:
return state;
}
};
const [state, dispatch] = useReducer(reducer, initialState);
useEffect(() => {
// fetch, axios, ajax
fetch(url)`
.then(response => {
dispatch({type: 'SUCCSSS', payload: response});
})
.catch(err => {
dispatch({type: 'ERROR'});
})
}, [id])
##### useMemo
useMemo用于内存优化,将函数返回结果在内存缓存起来,如果没有变化,就不会重新计算。
`jsx
const Counter = () => {
const [count1, setCount1] = useState(0);
const [count2, setCount2] = useState(0);
// 当count1有变化,使用内存备忘录来记住count1计算出的值
const isEven = useMemo( () => {
let i = 0;
while(i < 2000000000) i++;
return count1 % 2 === 0;
}, [count1]);
return (
##### useCallback
React默认父组件的重新渲染会导致子组件的重新渲染。React在function的组件中,所有function都会在render时作为一个全新的function,但是大多数情况下我们不需要这样的函数,此时我们可以在组件上使用React.memo(component)并配合useCallback(() => {// change state code}, [field]), 这样可以减少很多自组件不必要的渲染。
`jsx
import {useState, useMemo, useCallback} from 'react';const Title = React.memo(function () {
console.log('Rendering Title')
return (
useCallback Hook
)
});const Button = React.memo(
function({ handleClick, children }) {
console.log('Rendering button - ', children)
return (
)
}
);
const Count = React.memo(
function({ text, count }) {
console.log(
Rendering ${text})
return {text} - {count}
}
);
function ParentComponent() {
const [age, setAge] = useState(25)
const [salary, setSalary] = useState(50000)
const incrementAge = useCallback(() => {
setAge(age + 1)
}, [age])
const incrementSalary = useCallback(() => {
setSalary(salary + 1000)
}, [salary])
return (
)
}
`##### useRef, 用于和DOM元素进行通信,或存储组件的某些属性如:this.xxx
`jsx
// 和DOM元素通信
function FocusInput() {
const inputRef = useRef(null)
useEffect(() => {
inputRef.current.focus()
}, [])
return (
)
}
// 存储组件属性
function HookTimer() {
const [timer, setTimer] = useState(0)
const interValRef = useRef()
useEffect(() => {
interValRef.current = setInterval(() => {
setTimer(timer => timer + 1)
}, 1000)
return () => {
clearInterval(interValRef.current)
}
}, [])
return (
HookTimer - {timer} -
)
}
`##### 自定义hook,自定义hook本质上是对原生hook的一种封装。
`jsx
// 例1
function useDocumentTitle(count) {
useEffect(() => {
document.title = Count ${count}
}, [count])
}
// 例2
function useCounter(initialCount = 0, value) {
const [count, setCount] = useState(initialCount)
const increment = () => {
setCount(prevCount => prevCount + value)
}
const decrement = () => {
setCount(prevCount => prevCount - value)
}
const reset = () => {
setCount(initialCount)
}
return [count, increment, decrement, reset]
}
// 例3
function useInput(initialValue) {
const [value, setValue] = useState(initialValue)
const reset = () => {
setValue('')
}
const bind = {
value,
onChange: e => {
setValue(e.target.value)
}
}
return [value, bind, reset]
}
``