小編給大家分享一下Redux是什么,相信大部分人都還不怎么了解,因此分享這篇文章給大家參考一下,希望大家閱讀完這篇文章后大有收獲,下面讓我們一起去了解一下吧!
Redux 是 React 生態系統中的革命性技術。它使我們能夠在全局范圍內存儲不可變數據,并解決了在組件樹中 prop-drilling 的問題。需要在應用程序之間共享不可變數據時,它現在依舊是一種可以方便擴展的優秀工具。
React 這樣的單頁應用程序(SPA)的出現為我們開發 Web 應用程序的方式帶來了許多變化。它將我們的后端與前端代碼分離開來,使我們能夠專心一致并分離出關注點。圍繞狀態,它還引入了很多復雜性。
現在,異步獲取數據意味著數據必須位于兩個位置:前端和后端。我們必須考慮如何在全局范圍內以最佳方式存儲這些數據,以便它們能對我們的所有組件都可用,同時保持數據緩存以減少網絡延遲?,F在,前端開發中的很大一部分負擔來自于我們的全局存儲的維護工作,我們還要確保這些存儲不會遭受狀態錯誤、數據非規范化和陳舊數據的困擾。
使用 Redux 和類似的狀態管理庫時,大多數人都會遇到的一大問題是,我們會將其視為后端狀態的緩存。我們獲取數據,通過 reducer/action 將其添加到存儲中,并定期重新獲取以確保它是最新的。
我們用 Redux 做的事情太多了,甚至把它看成是解決問題的全面解決方案。
關鍵在于,我們的前端和后端狀態永遠不會真正同步,我們最多可以營造一種它們同步的錯覺。這是客戶端 - 服務器模型的缺點之一,也是為什么我們需要緩存的原因所在。但是,同步緩存和保持狀態是非常復雜的,因此我們不應該像 Redux 鼓勵的那樣,從頭開始重新創建這個后端狀態。
當我們開始在前端重新創建數據庫時,后端和前端之間的職責界限很快就變得模糊不清。作為前端開發人員,我們不需要完全了解表及其關系即可創建簡單的 UI。
我們也不必知道如何高水平地標準化我們的數據。這種責任應該落在設計表的那些人(后端開發人員)身上。然后,后端開發人員可以用文檔化的 API 形式為前端開發人員提供抽象。
現在,人們圍繞 Redux 構建了無數的庫(redux-observable、redux-saga 和 redux-thunk 等),以幫助我們管理后端數據,每個庫都為已經繁瑣不已的庫又增加了一層復雜性。我相信其中大多數都沒有達成目標。有時為了前進。我們需要先退后一步。
如果我們不再在前端代碼中管理后端狀態,而只是將其視為需要定期更新的緩存會怎么樣呢?將前端視為從緩存讀取內容的簡單顯示層后,我們的代碼就會變得更加易用,并且更適合純前端開發人員閱讀。我們獲得了分離關注點的所有好處,同時避開了構建 SPA 的大部分缺點。
我認為有兩個庫比使用 Redux(或類似的狀態管理庫)存儲后端狀態要好用很多。
我已經在自己的多數個人和工作項目中使用 React Query 幾個月了。這個庫有一個非常簡單的 API 和幾個 hooks,用于管理查詢(獲取數據)和突變(更改數據)。
自從使用 React Query 之后,我不僅提升了效率,而且最終編寫的樣板代碼比 Redux 少了 9 成。我發現自己更容易將注意力集中在前端應用程序的 UI/UX 上,不會再時刻操心整個后端狀態了。
要對比這個庫和 Redux 的話,我們來看這兩種方法的一個代碼示例。我使用常規 JS、React Hooks 和 axios 實現了一個從服務器獲取的簡單 TODO 列表。
import React, { useEffect } from "react"; import { useSelector, useDispatch } from "react-redux"; import axios from 'axios'; const SET_TODOS = "SET_TODOS"; export const rootReducer = (state = { todos: [] }, action) => { switch (action.type) { case SET_TODOS: return { ...state, todos: action.payload }; default: return state; } }; export const App = () => { const todos = useSelector((state) => state.todos); const dispatch = useDispatch(); useEffect(() => { const fetchPosts = async () => { const { data } = await axios.get("/api/todos"); dispatch({ type: SET_TODOS, payload: data} ); }; fetchPosts(); }, []); return ( <ul>{ todos.length > 0 && todos.map((todo) =>{ <li>{todo.text}</li> } ) } </ul> ); };
請注意,到這里甚至還沒有開始處理重新獲取、緩存和無效化,只是加載數據并在加載時將其存儲在全局存儲中而已。
import React from "react"; import { useQuery } from "react-query"; import axios from "axios"; const fetchTodos = () => { const { data } = axios.get("/api/todos"); return data; }; const App = () => { const { data } = useQuery("todos", fetchTodos); return data ? ( <ul>{data.length > 0 && data.map((todo) => <li>{todo.text}</li>)}</ul> ) : null; };
默認情況下,上面的示例包括具有合理默認值的數據重新獲取、緩存和過時內容無效化。你可以在全局級別設置緩存配置,然后就可以忘掉它了——一般來說它足以完成你期望的工作
現在,無論需要什么數據,你都可以將 useQuery hook 與你設置的唯一鍵(在本例中為“todos”)一起使用,并使用異步調用來獲取數據。
要更改接口狀態時,React Query 提供了 useMutation hook。
一旦你開始使用這個庫,就會發現在絕大多數項目中 Redux 都太笨重了。處理完應用程序的數據獲取 / 緩存部分后,前端幾乎沒有全局狀態可處理??梢允褂?Context 或 useContext+useReducer 處理剩下的少量內容,代替 Redux 的作用。
或者更好的方法是,使用 React 的內置狀態作為你的簡單前端狀態,這樣做肯定沒問題的。
// clean, beautiful, and simple const [state, setState] = useState();
我們應該更徹底地分離后端與前端,而不是陷在這種模棱兩可的中間狀態里。
以上是“Redux是什么”這篇文章的所有內容,感謝各位的閱讀!相信大家都有了一定的了解,希望分享的內容對大家有所幫助,如果還想學習更多知識,歡迎關注億速云行業資訊頻道!
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。