react18之 05 hook之 useReducer 处理state数据有add或者sub几个操作state数据、实现对一个数据的增删改操作、登录几种状态的处理
useReducer的使用
- 使用useReducer,一般来说就是state之中的数据eg:count有几个操作,比如自增、自减、乘法等状态操作count值,这时候使用useReducer中定义一个纯函数来管理最为方便
01: useReducer的正常使用
useReducer.jsx
import React, {
useReducer } from 'react';
function oneReducer(state,action){
switch(action.type) {
case 'add':
return {
count:state.count + 1};
case 'sub':
return {
count:state.count - 1};
case 'mul':
return {
count:state.count * action.playod.num};
default:
throw new Error();
}
}
export default function UseReducer(props) {
const [state,dispatch] = useReducer(oneReducer,{
count:1})
function addcount(){
dispatch({
type:'add'})
}
function subcount(){
dispatch({
type:'sub'})
}
function mulcount(){
dispatch({
type:'mul',playod:{
num:2}})
}
return (
<div className='content'>
UseReducer - count - {
state.count }
<div><button onClick={
addcount}>add++</button></div>
<div><button onClick={
subcount}>sub--</button></div>
<div><button onClick={
mulcount}>mul**</button></div>
</div>
)
}
效果
02: useReducer的惰性使用
UseReducer.jsx
import React, {
useReducer } from 'react';
function init(initialCount) {
return {
count: initialCount}
}
function reducer(state, action) {
console.log('state',state,"action",action);
switch (action.type) {
case 'add':
return {
count: state.count + 1};
case 'sub':
return {
count: state.count - 1};
case 'mul':
return {
count:state.count * action.playod.num};
case 'reset':
return init(action.payload);
default:
throw new Error();
}
}
export default function UseReducer惰性(props) {
const initialState = 1
const [state, dispatch] = useReducer(reducer, initialState, init);
function addcount(){
dispatch({
type:'add'})
}
function subcount(){
dispatch({
type:'sub'})
}
function mulcount(){
dispatch({
type:'mul',playod:{
num:2}})
}
function resetcount(){
dispatch({
type:'reset',payload:10})
}
return (
<div className='content'>
UseReducer惰性 - count - {
state.count }
<div><button onClick={
addcount}>add++</button></div>
<div><button onClick={
subcount}>sub--</button></div>
<div><button onClick={
mulcount}>mul**</button></div>
<div><button onClick={
resetcount}>reset</button></div>
</div>
)
}
效果
03: useReducer的实现一个增删改
UseReducer的增删改.jsx
import React, {
useReducer } from 'react';
import Add from "./Add";
import ListCom from "./List";
export default function UseReducer的增删改(props) {
const initialTasks = []
const [list, dispatch] = useReducer(tasksReducer,initialTasks)
function tasksReducer(state, action) {
switch (action.type) {
case 'add': {
return [...state, {
id: action.id,
text: action.text
}];
}
case 'edit': {
return state.map(t => {
if (t.id === action.list.id) {
return action.list;
} else {
return t;
}
});
}
case 'deleted': {
return state.filter(t => t.id !== action.id);
}
default: {
throw Error('Unknown action: ' + action.type);
}
}
}
function addFuc(text){
dispatch({
type:'add',id: +new Date(),text:text})
}
function delFuc(id){
dispatch({
type:'deleted',id:id})
}
function editFuc(item){
dispatch({
type:'edit', list:item })
}
return (
<div className='content'>
UseReducer的增删改
<div>
<Add addFuc={
addFuc}></Add>
<ListCom list={
list} delFuc={
delFuc} editFuc={
editFuc}></ListCom>
</div>
</div>
)
}
Add.jsx
import React, {
useState } from 'react';
export default function Add(props) {
const {
addFuc } = props
const [keyword, setKeyword] = useState('')
function add(){
addFuc(keyword)
setKeyword('')
}
function keywordChange(event){
let keyword = event.target.value
setKeyword(keyword)
}
return (
<div className='content'>
<input type="text" value={
keyword} onChange={
keywordChange}/><button onClick={
add}>add</button>
</div>
)
}
List.jsx
import React from 'react';
import ListItem from "./ListItem";
export default function List(props) {
const {
list,delFuc,editFuc } = props
return (
<div>
{
list.map(item=>{
return (
<ListItem key={
item.id} listItem={
item} delFuc={
delFuc} editFuc={
editFuc}></ListItem>
)
})
}
</div>
)
}
ListItem.jsx
import React, {
useState } from 'react';
export default function ListItem(props) {
const {
listItem,delFuc,editFuc } = props;
const [isEditing, setIsEditing] = useState(false);
function del(id){
delFuc(id)
}
function edit(){
setIsEditing(!isEditing)
}
let taskContent;
function save(){
setIsEditing(false)
}
function textChange(event){
editFuc({
...listItem,text:event.target.value})
}
if (isEditing) {
taskContent = (
<span>
<input type="text" value={
listItem.text} onChange={
textChange}/> <button onClick={
save}>保存</button>
</span>
)
} else {
taskContent = (
<span>
{
listItem.text }
<button onClick={
()=>{
edit(listItem) }}>编辑</button>
</span>
)
}
return (
<div>
{
taskContent }
<button onClick={
()=>{
del(listItem.id) }}>删除</button>
</div>
)
}
效果
04: 使用useReducer管理登陆的几种状态(写入字段、登陆、成功、失败、退出)几种状态
code.jsx
import React, {
useReducer } from 'react';
const initState = {
username:'',
password:'',
isLoading:false,
isError:false,
isLoggedIn:false
}
function login({
username, password }) {
return new Promise((resolve, reject) => {
setTimeout(() => {
if (username === 'name' && password === 'pass') {
resolve({
code:200,msg:'登陆成功'});
} else {
reject({
code:0,msg:'登陆失败'});
}
}, 1000);
});
}
function loginReducer(state, action) {
switch (action.type) {
case 'field': {
return {
...state,
[action.filedName] : action.value
}
}
case 'login': {
return {
...state,isLoading:true,isError:false,isLoggedIn:false}
}
case 'success': {
return {
...state,isLoading:false,isError:false,isLoggedIn:true}
}
case 'error': {
return {
...state,isLoading:false,isError:true,isLoggedIn:false}
}
case 'logOut': {
return {
...state,isLoading:false,isError:false,isLoggedIn:false,username:'',password:''}
}
default: {
throw Error('Unknown action: ' + action.type);
}
}
}
export default function UseReducerLogin(props) {
const [state, dispatch] = useReducer(loginReducer,initState)
const {
username,password,isLoading,isError,isLoggedIn } = state
async function onSubmit(e){
e.preventDefault();
dispatch({
type:'login'})
try {
const res = await login({
username,password})
if ( res.code === 200 ) {
dispatch({
type:'success'})
} else {
dispatch({
type:'error'})
}
} catch (err) {
dispatch({
type:'error'})
}
}
function usernameChange(event){
dispatch({
type:'field',
filedName:'username',
value:event.target.value
})
}
function passwordChange(event){
dispatch({
type:'field',
filedName:'password',
value:event.target.value
})
}
function logOut(){
dispatch({
type:'logOut'})
}
return (
<div>
{
isLoggedIn ?
<>
<p>欢迎 {
username }登陆成功。<button onClick={
logOut}>退出登陆</button> </p>
</>
:
<>
{
isError ? '用户名或者密码错误' : ''}
<form onSubmit={
onSubmit}>
<div>
用户名:<input type="text" value={
username} onChange={
usernameChange}/>
</div>
<div>
密码:<input type="password" value={
password} onChange={
passwordChange}/>
</div>
<button type='submit' disabled={
isLoading}>
{
isLoading ? '登陆中...' : '登陆'}
</button>
</form>
</>
}
</div>
)
}
效果