2020 年 React 狀態管理

原文地址: medium.com/better-prog…
譯文地址:github.com/xiao-T/note…
本文版權歸原做者全部,翻譯僅用於學習。react


咱們是否還須要 Redux 和 Mobx 這類的狀態管理框架?git

引言

React hooks 的引入無疑改變的了 state 管理的現狀。github

在此以前,很難在組件之間共享 state 相關的邏輯。如今,咱們能夠很簡單的經過抽象一個 hook 來處理(例如:useUserLogin)。api

這就引出了問題,爲何咱們還須要狀態管理框架?在這篇文章中,我將展現個人決策過程:如何管理 state。關於在2020年咱們是否還須要 state 管理框架,我也會分享個人觀點。框架

有什麼變化?

在有 Hooks 以前,咱們是如何定義 state 的?基本上,有兩種選擇:在組件內部定義本地 state,或者用一個 state 管理框架設置全局的 state (例如:Mobx/Redux)。工具

本地 state (hooks 以前)

export class UserList extends Component {
    state = {
        isLoading: false,
        hasError: false,
        users: []
    }

    searchUsers(value) {
        this.setState({isLoading: true});

        api.get(`/users?searchKey=${value}`)
            .then((data) => this.setState({users: data}))
            .catch(() => this.setState({hasError: true}))
            .finally(() => this.setState({loading: false}));
    }

    render() {
        if (this.state.isLoading) {
            // render loading spinner
        }
        
        if (this.state.hasError) {
            // render error message
        }

        return (
            <div> <input onChange={(event) => this.searchUsers(event.target.value)} /> </div> ) } } 複製代碼

在接下來咱們會說明只有這兩個選擇時帶來的問題。假設,咱們的 state 沒必要設爲全局,可是,咱們但願能夠在多個組件複用 state,咱們該如何定義本地 state。學習

在上面的演示中,咱們或許想複用 loading 和 error state,在 Hooks 以前,是不可能的。惟一的選擇是須要利用 Redux 來複用它。在 Redux 中,任何須要搜索用戶的組件只需簡單 dispatch 一個 action(searchUsers())和監聽全局 state 的變化便可。開發工具

然而,使用這些全局 state(Redux/Mobx)會帶來一些問題:this

  • 更多的樣板代碼
  • 複雜的數據流
  • 多個組件同時維護全局 state,這能夠能會帶來意想不到的反作用。

解決方案:React Hooks!

謝天謝地 React v16.8 引入的 Hooks。從這時起,在作組件之間共享 state 相關的邏輯變得可行。spa

在下面的演示中,咱們能夠共享 loading 和 error 的行爲:

import {useState} from 'react';

const useRequestHandler = () => {
    const [isLoading, setLoading] = useState(false);
    const [hasError, setError] = useState(false);
    const [data, setData] = useState(null);

    const handleRequest = (request) => {
        setLoading(true);
        setError(false);

        return api.get(request)
            .then(setData)
            .catch(() => setError(true))
            .finally(() => setLoading(false))
    };

    return {isLoading, hasError, data, handleRequest};
};


const UserList = () => {
    const {data, isLoading, hasError, handleRequest} = useRequestHandler();
    
    const searchUsers = (value) => handleRequest(`/users?searchKey=${value}`);
  
    return (
        <React.Fragment> {data.map(u => <p>{u.name}</p>)} </React.Fragment> ) } 複製代碼

更多好處:若是,多個組件須要搜索用戶列表的功能,咱們也能夠自定義 useUserSearch hook。

然而,hooks 並非銀彈。把 state 保存在 hook 中,並不意味着它就變成了單例對象,它只是綁定在一個組件中。在某些狀況下,咱們只想保留一個實例 state 對象(例如:只加載一次用戶信息)。這是 state 管理框架提供的功能。

如何,什麼時候,何地管理 state

如今,能夠在多個組件之間共享 state 相關邏輯了,那咱們怎麼決定 state 保存在組件內(本地),仍是保存在 state 管理框架中(全局)呢?

下面的圖片展現了個人決策過程。

State 管理框架有什麼好處呢?

如今,咱們知道如何在全局和本地作抉擇了。可是,在2020年爲何還須要 state 管理框架呢?這相比 React Hooks 有什麼好處呢?

有如下幾個好處:

  • 全局定義,也表明只有一個實例對象
  • 只會加載一次遠程數據
  • 開發工具的支持
  • 爲軟件工程師提供了一種標準的開發方式

總結

咱們看到 React Hooks 已經攪動了 state 管理的格局。因爲它們的引入,在組件之間共享 state 相關邏輯變得更加簡單。

然而,Hooks 並非銀彈,咱們仍舊須要 state 管理框架。這也並非說要讓全部的 state 都是全局的 — 大多狀況下讓其保留在組件之間更加好。只有在有絕對必要的狀況下,才把 state 移動到 state 管理框架中。

相關文章
相關標籤/搜索