一.useState
// 新建文件,在 App.js 中引入
import React, { useState } from 'react'
const FruitList = ({ fruits, onSetFruit }) => {
return (
<ul>
{fruits.map(item => <li key={item} onClick={() => onSetFruit(item)}>{item}</li>)}
</ul>
)
}
const FruitAdd = (props) => {
const [name, setName] = useState('') // name: 变量, setName: 设置变量的方法
const onAddFruit = e => {
if (e.key === 'Enter') {
props.onAddFruit(name)
setName('')
}
}
return (
<div>
<input
type="text"
value={name}
onChange={e => setName(e.target.value)}
onKeyDown={onAddFruit}
/>
</div>
)
}
const HooksTest = () => {
const [fruit, setFruit] = useState('')
const [fruits, setFruits] = useState(['香蕉', '草莓', '芒果'])
return (
<div>
<p>{fruit === '' ? '请选择喜爱的水果:' : `您的选择是: ${fruit}`}</p>
<FruitList fruits={fruits} onSetFruit={setFruit} ></FruitList>
<FruitAdd onAddFruit={name => setFruits([...fruits, name])} />
</div>
)
}
export default HooksTest;
提示: useState 最好是在最顶层调用, 组件每次渲染的 useState 数量必须要一致, 必须要完全相同的顺序调用. 推荐一个 eslint 用来检测 hooks 的包 (eslint-plugin-react-hooks)
// package.json
"eslintConfig": {
"extends": "react-app",
"plugins": [
"react-hooks"
],
"rules": {
"react-hooks/rules-of-hooks": "error"
}
},
二.useEffect
useEffect(() => { // 副作用操作保存: dom 操作, 定时器, ajax
console.log(11111)
return () => { // 相当于 componentWillUnmount 钩子
console.log(222222)
}
}, []) // 参数 2 指的依赖的状态, [] 中的值变化 useEffect 中的方法执行, 本案例只需执行一次,所以为空数组
三.useReducer
import React, { useState, useEffect, useReducer } from 'react'
const fruitReducer = (state, action) => {
switch (action.type) {
case 'init':
return action.payload;
case 'add':
return [...state, action.payload];
default:
return state;
}
}
const FruitList = ({ fruits, onSetFruit }) => {
return (
<ul>
{fruits.map(item => <li key={item} onClick={() => onSetFruit(item)}>{item}</li>)}
</ul>
)
}
const FruitAdd = (props) => {
const [name, setName] = useState('')
const onAddFruit = e => {
if (e.key === 'Enter') {
props.onAddFruit(name)
setName('')
}
}
return (
<div>
<input
type="text"
value={name}
onChange={e => setName(e.target.value)}
onKeyDown={onAddFruit}
/>
</div>
)
}
const HooksTest = () => {
const [fruit, setFruit] = useState('')
// const [fruits, setFruits] = useState(['苹果', '橘子', '葡萄'])
// 参数 1 是reducer
// 参数 2 是初始值
const [fruits, dispatch] = useReducer(fruitReducer, [])
useEffect(() => {
dispatch({ type: 'init', payload: ['苹果', '橘子']})
}, [])
return (
<div>
<p>{fruit === '' ? '请选择喜爱的水果:' : `您的选择是: ${fruit}`}</p>
<FruitList fruits={fruits} onSetFruit={setFruit} ></FruitList>
<FruitAdd onAddFruit={name => dispatch({ type: 'add', payload: name})} />
</div>
)
}
export default HooksTest;
四.useContext
import React, { useState, useEffect, useReducer, useContext } from 'react'
const Context = React.createContext()
const { Provider } = Context
const fruitReducer = (state, action) => {
switch (action.type) {
case 'init':
return action.payload;
case 'add':
return [...state, action.payload];
default:
return state;
}
}
const FruitList = ({ fruits, onSetFruit }) => {
return (
<ul>
{fruits.map(item => <li key={item} onClick={() => onSetFruit(item)}>{item}</li>)}
</ul>
)
}
const FruitAdd = (props) => {
const [name, setName] = useState('')
const { dispatch } = useContext(Context)
const onAddFruit = e => {
if (e.key === 'Enter') {
// props.onAddFruit(name)
// setName('')
dispatch({ type: 'add', payload: name })
setName('')
}
}
return (
<div>
<input
type="text"
value={name}
onChange={e => setName(e.target.value)}
onKeyDown={onAddFruit}
/>
</div>
)
}
const HooksTest = () => {
const [fruit, setFruit] = useState('')
// const [fruits, setFruits] = useState(['苹果', '橘子', '葡萄'])
// 参数 1 是reducer
// 参数 2 是初始值
const [fruits, dispatch] = useReducer(fruitReducer, [])
useEffect(() => {
dispatch({ type: 'init', payload: ['苹果', '橘子'] })
}, [])
return (
<Provider value={{ fruits, dispatch }}>
<p>{fruit === '' ? '请选择喜爱的水果:' : `您的选择是: ${fruit}`}</p>
<FruitList fruits={fruits} onSetFruit={setFruit} ></FruitList>
<FruitAdd />
</Provider>
)
}
export default HooksTest;
网友评论