新聞中心
本系列文章 "React 狀態(tài)管理" 也是希望能幫助到大家了解不同狀態(tài)管理方案(React 官方本身提供的及社區(qū)的一些庫)能做的事情有哪些及優(yōu)略點(diǎn)。

成都創(chuàng)新互聯(lián)專注于瑯琊網(wǎng)站建設(shè)服務(wù)及定制,我們擁有豐富的企業(yè)做網(wǎng)站經(jīng)驗(yàn)。 熱誠為您提供瑯琊營銷型網(wǎng)站建設(shè),瑯琊網(wǎng)站制作、瑯琊網(wǎng)頁設(shè)計、瑯琊網(wǎng)站官網(wǎng)定制、小程序制作服務(wù),打造瑯琊網(wǎng)絡(luò)公司原創(chuàng)品牌,更為您提供瑯琊網(wǎng)站排名全網(wǎng)營銷落地服務(wù)。
本篇先從 React 本身提供的組件狀態(tài)管理開始。React 的組件狀態(tài)分為類組件時代的 和當(dāng)下函數(shù)組件的 hooks API 管理數(shù)據(jù)狀態(tài)。
類組件
State類組件將組件內(nèi)所有的狀態(tài)放在一個 state 中管理: 獲取狀態(tài)數(shù)據(jù)、 更新狀態(tài)數(shù)據(jù)。
import React from 'react';
class State extends React.Component {
constructor() {
super();
this.state = {
count: 0,
}
}
render() {
return
count: {this.state.count}
}
}
export default State;
函數(shù)組件 useState
React 16.8 發(fā)布后,函數(shù)組件成為熱門選擇,組件狀態(tài)使用 useState() 函數(shù),相比類組件狀態(tài)拆分的更細(xì)并且每次更新狀態(tài)變量都是替換而不是合并。
如果更新依賴于先前的狀態(tài),可以將函數(shù)傳遞給 setState,并返回一個更新后的值 setState(preState => newState)。 熟悉 Redux 的朋友看起來也許不陌生,該函數(shù)是不是更像一個 reducer 函數(shù)?
示例:useState 實(shí)現(xiàn)計數(shù)器增、減、重置。
import { useState } from 'react';
const State = () => {
const [count, setCount] = useState(0);
return
計數(shù)器 count: {count}
}
export default State;
函數(shù)組件 useReducer
剛開始看到 useReducer 時,還聯(lián)想和 Redux 之間有什么關(guān)系?需要注意的是和 Redux 完全不是一個東西,useReducer 是 React Hooks 提供的一個 API,如果熟悉 Redux 可能看起來會更熟悉。
useReducer 是 useState 的替代方案,主要用來處理一些邏輯比較復(fù)雜的 state 或 下一個 state 依賴于前一個 state 等。
Example:使用 useReducer 重寫上面的計數(shù)器示例,可以和上面的 useState 做一個對比。
import { useReducer } from "react"
const COUNT_INCREMENT = 'COUNT_INCREMENT';
const COUNT_DECREMENT = 'COUNT_DECREMENT';
const COUNT_RESET = 'COUNT_RESET';
const initialState = {
count: 0,
};
const reducer = (state, action) => {
switch (action.type) {
case COUNT_INCREMENT:
return { count: state.count + 1 };
case COUNT_DECREMENT:
return { count: state.count - 1 };
case COUNT_RESET:
return { count: initialState.count };
default:
return state;
}
};
const State = () => {
const [state, dispatch] = useReducer(reducer, initialState);
return
計數(shù)器 count: {state.count}
}
export default State;
useReducer 實(shí)現(xiàn) Todos
使用 useReducer 實(shí)現(xiàn)一個稍微復(fù)雜點(diǎn)的功能,例如 Todos,有創(chuàng)建、更新、移除待辦事項功能,你可以試想下如果換做 useState 該怎么處理?會不會更麻煩?
減速機(jī)實(shí)現(xiàn)
在 目錄下實(shí)現(xiàn) reducer 需要的邏輯,定義的 initialState 變量、reducer 函數(shù)都是為 useReducer 這個 Hook 做準(zhǔn)備的,這里的 reducer 函數(shù)是一個純函數(shù)。
// src/reducers/todos-reducer.jsx
export const TODO_LIST_ADD = 'TODO_LIST_ADD';
export const TODO_LIST_EDIT = 'TODO_LIST_EDIT';
export const TODO_LIST_REMOVE = 'TODO_LIST_REMOVE';
const randomID = () => Math.floor(Math.random() * 10000);
export const initialState = {
todos: [{ id: randomID(), content: 'todo list' }],
};
const reducer = (state, action) => {
switch (action.type) {
case TODO_LIST_ADD: {
const newTodo = {
id: randomID(),
content: action.payload.content
};
return {
todos: [ ...state.todos, newTodo ],
}
}
case TODO_LIST_EDIT: {
return {
todos: state.todos.map(item => {
const newTodo = { ...item };
if (item.id === action.payload.id) {
newTodo.content = action.payload.content;
}
return newTodo;
})
}
}
case TODO_LIST_REMOVE: {
return {
todos: state.todos.filter(item => item.id !== action.payload.id),
}
}
default: return state;
}
}
export default reducer;
創(chuàng)建 Todos 組件
下面進(jìn)行待辦事項組件開發(fā),細(xì)分為 TodoAdd、Todo、Todos 三個組件,在 Todos 組件內(nèi)使用 useReducer 獲取組件需要的狀態(tài)(state)和更新狀態(tài)的方法(dispatch)。
添加、更新、刪除待辦事項行為分別在 TodoAdd、Todo 組件中,以下我們使用的是 React 推薦的 組合組件模式,可以通過 props 從父組件傳遞數(shù)據(jù)到子組件。
import { useReducer, useState } from "react";
import reducer, { initialState, TODO_LIST_ADD, TODO_LIST_EDIT, TODO_LIST_REMOVE } from "../../reducers/todos-reducer";
const TodoAdd = ({ dispatch }) => {
const [content, setContent] = useState('');
return <>
setContent(e.target.value)} />
>
};
const Todo = ({ todo, dispatch }) => {
const [isEdit, setIsEdit] = useState(false);
const [content, setContent] = useState(todo.content);
return
{
!isEdit ? <>
{todo.content}
> : <>
setContent(e.target.value) } />
>
}
}
const Todos = () => {
const [state, dispatch] = useReducer(reducer, initialState);
return <>
{
state.todos.map(todo => key={todo.id}
todo={todo}
dispatch={dispatch}
/>)
}
>
}
export default Todos;
總結(jié)
useState 適合定義一些單一的狀態(tài),useReducer 適合邏輯比較復(fù)雜的狀態(tài)。
一個好的經(jīng)驗(yàn)法則是:"如果狀態(tài)是基本的數(shù)據(jù)類型(字符串、數(shù)值型、布爾型)可以選擇 useState,如果是數(shù)組或?qū)ο蟮绕渌鼜?fù)雜的類型或復(fù)雜邏輯時最好選擇 useReducer"。
但是兩者都是組件的狀態(tài)管理,當(dāng)多個組件協(xié)同工作時不得不面對組件間 "數(shù)據(jù)通信" 問題。
React 組件數(shù)據(jù)狀態(tài)流轉(zhuǎn)是一個 "單項數(shù)據(jù)流" 的理念。簡單的組件可以通過 props 傳遞數(shù)據(jù)狀態(tài),當(dāng)組件過多時,層層 Props 傳遞的方式顯的就有點(diǎn)過于繁瑣了,不易維護(hù)。
新聞名稱:React狀態(tài)管理—useState和useReducer如何選擇?
文章源于:http://m.fisionsoft.com.cn/article/ccedijg.html


咨詢
建站咨詢
