Hooks是React16.8新增的,它可以让你不编写class的情况下使用state及其他React特性。
Hooks特点:
-无需修改组件结构的情况下复用状态逻辑
-可将组件中相互关联的部分拆分成更小的函数,复杂组件将变得更容易理解
-更简洁、更易理解的代码
App.js引入这个组件
pages/HooksPage.js
import React ,{useState,useEffect} from 'react'
import FruitList from "../components/FruitList"//default导出这么写
import FruitAdd from "../components/FruitAdd"//default导出这么写
export default function HooksPage() {
//useState返回第一个参数是结果值 第二个参数是set方法
// const [date, setDate] = useState(new Date());
const [counter, setCounter] = useState(0);
const [fruits, setFruits] = useState(["apple","banana"]);
//useEffect 有点像生命周期钩子 事件不能写在useEffect里面 因为当useEffect执行的时候 dom已经更新完成了
//空数组不写相当于componentDidUpdate 写了之后相当于componentDidMount return 函数相当于componentDidUnMount
// useEffect(() => {
// // effect
// const timer = setInterval(() => {
// setDate(new Date());
// },1000);
// return () => {
// clearInterval(timer);
// };
// }, [])
const handleCounter = () => {
setCounter(counter+1);
}
return (
<div>
<h1>HooksPage</h1>
{/* <p>{useClock().toLocaleTimeString()}</p> */}
<div onClick={handleCounter}>{counter}</div>
<FruitAdd addFruit={name => setFruits([...fruits,name])}/>
<FruitList fruits={fruits} setFruits={setFruits}/>
</div>
)
}
//自定义hook 必须用use+首字母大写命名
// function useClock(){
// const [date, setDate] = useState(new Date());
// useEffect(() => {
// // effect
// const timer = setInterval(() => {
// setDate(new Date());
// },1000);
// return () => {
// clearInterval(timer);
// };
// }, [])//[date]这样写 直接值改变 useEffect就会执行
// return date;
// }
components/FruitList
import React from 'react'
//显示水果列表
export default function FruitList({fruits,setFruits}){//解构props
//点击删除所在li
const delFruit = (index)=>{
const tem = [...fruits];
tem.splice(index,1);
setFruits(tem);
}
return (
<ul>
{
fruits.map((item,index) => {
return <li key={index} onClick={()=> delFruit(index)}>{item}</li>
})
}
</ul>
)
}
components/FruitAdd
import React,{useState} from 'react'
export default function FruitAdd({addFruit}) {
const [name, setname] = useState('');
return (
<div>
<input value={name} onChange={event=>setname(event.target.value)}/>
<button onClick={()=> addFruit(name)}>add</button>
</div>
)
}
useReducer
reducer是个纯函数 接收旧的state和action 返回新的state
useReducer是useState的可选项 常用语组件有复杂状态逻辑时
pages/UseReducerPage.js
import React,{useReducer,useEffect} from 'react';
import FruitAdd from '../components/FruitAdd';
import FruitList from '../components/FruitList';
function fruitReducer(state=[],action){
switch(action.type){
case "replace":
case "init":
return [...action.payload];
case "add":
return [...state,action.payload];
default:
return state;
}
}
export default function UseReducerPage() {
const [fruits,dispatch] = useReducer(fruitReducer,[]);
useEffect(() => {
setTimeout(() => {
dispatch({type: "init",payload:['apple','banana']});
}, 1000);
return () => {
// cleanup
};
}, []);
return (
<div>
<FruitAdd addFruit={name => dispatch({type:'add',payload:name})}/>
<FruitList fruits={fruits} setFruits={
newList=>dispatch({
type: 'replace',
payload: newList
})
}/>
</div>
)
}
Hooks的context
pages/UseContextPage.js
import React,{useContext} from 'react'
import { Context } from '../AppContext'
export default function UseContextPage() {
const ctx = useContext(Context);
return (
<div>
<p>{ctx.user.name}</p>
</div>
)
}
App.js
传参
<Provider value={store}>
<UseContextPage/>
</Provider>
网友评论