摘要:歸約器函數負責返回應用當前全局狀態的表示形式。當我們在存儲上發送操作時將使用應用的當前狀態和導致狀態更新的操作來調用此歸約器函數。回到我們的歸約器我們可以檢查的動作類型并采取適當的步驟創建下一個狀態。我們將處理動作創造者中歸約器的副作用。
本文轉載自:眾成翻譯
譯者:iOSDevLog
鏈接:http://www.zcfy.cc/article/3811
原文:https://www.fullstackreact.com/30-days-of-react/day-19/
隨著我們了解了flux和Redux的知識,讓我們將Redux整合到我們的應用中,并通過連接的應用。
昨天, 我們討論了流量模式的原因, 它是什么, 我們有不同的選擇, 以及介紹了Redux。
今天, 我們將回到代碼和添加Redux在我們的應用。現在我們正在用它構建的應用是簡單的, 這只會顯示我們最后一次獲取當前時間的頁面。為了簡單起見, 我們不會調用遠程服務器, 只需使用 JavaScript 的Date 對象。
第一件事, 我們使用redux將不得不安裝redux庫。我們可以使用npm 包管理器來安裝redux。在我們以前構建的應用的根目錄中, 讓我們運行npm install 命令來安裝redux:
npm install --save redux
想使用redux, 我們還需要安裝另一個包, react-redux , 幫助我們把react 和 redux綁在一起。
npm install --save react-redux配置和設置
接下來的工作, 我們需要做的是在我們的應用內建立redux。我們需要執行以下操作才能設置它:
定義歸約
創建Store
創建動作創造者
將Store與我們的React意見聯系起來
得益
Precursor先驅第5步沒有promises, 但它會更好, 嗯?
我們少量地討論術語,(讓我們的手指移動是更重要的)。我們將只是稍微調整我們的應用(煩人, 我知道, 但這是最后一次), 所以我們為了提供數據通過我們的應用可以創建一個包裝組件。
完成后, 我們的應用樹將具有以下形狀:
[Root] -> [App] -> [Router/Routes] -> [Component]
廢話少說, 讓我們將我們的 src/App.js 移動到src/containers目錄中, 我們需要同時更新來自我們的導入的一些路徑。我們將使用幾天前討論的React路由材料。
我們將在
import React from "react"; import { BrowserRouter as Router, Route, Switch } from "react-router-dom" // We"ll load our views from the `src/views` // directory import Home from "./views/Home/Home"; import About from "./views/About/About"; const App = props => { return () } export default App;
此外, 我們將需要創建一個新的容器, 我們將調用Root , 這將包裝我們的整個
`touch src/containers/Root.js`
目前, 我們將在這里使用一個占位符組件, 但我們將在討論存儲時替換此內容。現在, 讓我們導出 _一些東西_:
import React from "react"; import App from "./App"; const Root = (props) => { return (); } export default Root;
最后, 讓我們更新的路由, 我們渲染我們的應用在src/index.js文件使用我們的新的Root 容器, 而不是它以前使用的App 。
import React from "react"; import ReactDOM from "react-dom"; import Root from "./containers/Root"; import "./index.css"; ReactDOM.render(添加Redux, document.getElementById("root") );
現在有了一個堅實的應用結構就位, 我們可以開始添加Redux。我們將采取的步驟以配合一些我們將建立的大多數應用的Redux結構通常都是相同的。我們需要:
寫一個根歸約器
寫 actionCreators
配置存儲、rootReducer和應用
將視圖連接到 actionCreators
我們故意保持這個高層次的介紹短一些, 所以堅持一下, 這一切都將在短期內變得更有意義。
讓我們設置允許我們添加Redux的結構。我們將在src/redux 目錄中完成幾乎所有的工作。讓我們創建該目錄。
mkdir -p src/redux touch src/redux/configureStore.js touch src/redux/reducers.js
首先我們先創建歸約器。雖然它聽起來很復雜, 但是歸約器實際上是相當直接的, 有一定的經驗。歸約器僅是 字面 函數。它的唯一責任是返回一個 next 狀態的表示。
在Redux模式, 不像flux, 我們只在 整個 應用處理 一個 全局存儲的。這使得事情變得更容易處理, 因為有一個地方的數據, 我們的應用生活。
root 歸約器函數負責返回應用當前全局狀態的表示形式。當我們在存儲上發送操作時, 將使用應用的當前狀態和導致狀態更新的操作來調用此歸約器函數。
讓我們在一個文件中建立我們的根歸約器在src/redux/reducers.js.。
// Initial (starting) state const initialState = { currentTime: new Date().toString() } // Our root reducer starts with the initial state // and must return a representation of the next state const rootReducer = (state = initialState, action) => { return state; } export default rootReducer
I在函數中, 我們將第一個參數定義為初始狀態 (第一次運行時, 不帶參數調用rootReducer , 因此它總是在第一次運行時返回 initialState )。
這就是現在的 rootReducer。就像現在這樣, state的價值總是和 initialState 一樣。在我們的例子中, 這意味著我們的數據樹有一個單一的currentTime鍵。
什么是動作?這里的第二個參數是從存儲區發送的操作。我們很快就會回來。現在,讓我們來看看動作。
最起碼, 一個動作 必須 包括一個type 鍵。type 鍵可以是我們想要的任何值, 但它必須存在。例如, 在我們的應用中, 我們將偶爾發送一項操作, 我們想告訴存儲獲取 最新 當前時間。我們可以將此操作稱為FETCH_NEW_TIME 的字符串值。
我們可能從我們的存儲發送的處理此更新的操作如下:
{ type: "FETCH_NEW_TIME" }
正如我們將通過鍵入這個字符串很多, 我們希望避免可能的拼寫錯誤的地方, 它是常見的創建一個types.js 文件, 將操作類型導出為常量。讓我們遵循這個約定, 創建一個src/redux/types.js 文件:
`export const FETCH_NEW_TIME = "FETCH_NEW_TIME";`
我們將從types.js 文件中引用它, 而不是使用"FETCH_NEW_TIME" 的硬編碼字符串調用該操作:
import * as types from "./types"; { type: types.FETCH_NEW_TIME, }
當我們想發送數據與我們的動作, 我們可以添加任何鍵, 我們想我們的動作。我們通常會看到這個所謂的payload 有效載荷, 但它可以被稱為任何東西。這是一個公約, 調用附加信息的payload。
我們的FETCH_NEW_TIME 動作將發送一個有效載荷與新的當前時間。因為我們想發送一個 序列化 值與我們的動作, 我們將發送新的當前時間的字符串值。
{ type: types.FETCH_NEW_TIME, payload: new Date().toString() // Any serializable value }
回到我們的歸約器, 我們可以檢查的動作類型, 并采取適當的步驟, 創建下一個狀態。在我們的情況下, 我們只儲存payload。如果操作的type 是FETCH_NEW_TIME, 我們將返回新的 currentTime (從我們的操作有效負載) 和其他狀態 (使用 ES6 擴展語法):
export const rootReducer = (state = initialState, action) => { switch(action.type) { case types.FETCH_NEW_TIME: return { ...state, currentTime: action.payload} default: return state; } }
請記住, 歸約 必須 返回一個狀態, 所以在默認情況下, _最起碼_確保返回當前狀態。
保持輕型化由于歸約器的功能每次調度一個動作, 我們要確保這些功能是盡可能簡單和快速。我們不希望他們造成任何副作用或有太多的延遲。
我們將處理動作創造者中歸約器的副作用。
在我們看動作創造者 (以及為什么我們稱他們為動作創造者) 之前, 讓我們把我們的存儲與我們的應用掛鉤。
我們將使用 react-redux 包將我們的視圖連接到我們的redux存儲。讓我們確保使用npm安裝此包:
npm install --save react-redux將存儲與視圖掛鉤
react-redux 包輸出一個名為 Provider 的組件。Provider 組件使存儲可以使用我們的應用中的所有容器組件, 而無需我們每次都需要手動傳遞它。
Provider 組件期望一個store 的屬性, 它期望是一個有效的redux存儲, 所以我們的應用沒有錯誤運行之前,我們需要完成一個configureStore 功能,。現在, 讓我們在應用中連接Provider 組件。我們將通過更新我們以前創建的包裝Root 組件來使用Provider 組件來完成此項。
import { Provider } from "react-redux"; // ... const Root = (props) => { // ... return (); }
請注意, 我們正在將store 值發送到Provider 組件, 但我們還沒有創建該存儲。現在我們來解決這個問題。
配置存儲為了創建一個存儲, 我們將使用新的src/redux/configureStore.js 來導出將負責創建存儲的函數。
我們如何創建一個存儲?
redux包輸出一個叫做 createStore 的函數, 它將為我們創建實際的存儲區, 因此, 讓我們打開 src/redux/configureStore.js 文件并導出一個稱為configureStore()的函數 (我們將很快定義), 并導入createStore` 幫助器:
import {createStore} from "redux"; // ... export const configureStore = () => { // ... } // ... export default configureStore;
實際上我們在我們的存儲還沒有返回任何東西, 所以讓我們實際創建的redux 存儲使用 createStore 的功能, 我們從redux導入:
import {createStore} from "redux"; export const configureStore = () => { const store = createStore(); return store; } export default configureStore;
如果我們在瀏覽器中加載我們的頁面, 我們將看到我們有一個巨大的錯誤: 沒有頁面得到渲染。
redux給我們的錯誤告訴我們, 我們存儲里沒有歸約器。如果沒有歸約器, 它將不知道如何處理動作或如何創建狀態等。為了越過這個錯誤, 我們需要參考我們創建的 rootReducer。
createStore 函數要求我們將 rootReducer 作為第一個參數來傳遞。它還希望將初始狀態作為第二個參數傳遞。我們將從我們創建的reducers.js 文件中導入這兩個值。
import { rootReducer, initialState } from "./reducers" // ... export const configureStore = () => { const store = createStore( rootReducer, // root reducer initialState, // our initialState ); return store; }
現在, 讓我們通過調用 configureStore() 函數創建store 的實例來更新我們的Root.js 文件。
const Root = (props) => { const store = configureStore(); return (連接視圖 (續)); }
我們的應用中的一切都設置為使用redux, 而無需 太 多開銷。redux 提供的一個更方便的方法是使用react-redux包導出的connect() 函數, 將狀態樹的片斷 綁定 到不同的組件。
connect() 函數返回一個函數, 它期望第一參數是一個組件。這通常叫做高階組件。
connect() 函數要求我們在函數中至少傳遞一個參數 (但通常我們會傳遞兩個)。它所期望的第一個參數是一個函數, 它將被稱為state 并期望一個返回的對象將數據連接到視圖。讓我們看看我們是否能在代碼中揭開這種行為的神秘面紗。
我們將這個函數稱為mapStateToProps 函數。因為它的責任是將狀態映射到與組件的原始props合并的對象。
讓我們在src/views/Home.js 中創建 home 視圖, 并使用此connect() 函數來綁定currentTime 在我們的狀態樹中的值。
import { connect } from "react-redux"; // ... const mapStateToProps = state => { return { currentTime: state.currentTime } } export default connect( mapStateToProps )(Home);
此connect() 函數 自動 將函數的第一個參數中的任何鍵傳遞為Home 組件的props 。
在我們的演示案例中, Home 組件中的currentTime屬性將映射到currentTime中的狀態樹鍵。讓我們更新 Home 組件, 以顯示currentTime中的值:
const Home = (props) => { return (); }Welcome home!
Current time: {props.currentTime}
雖然這個演示不是很有趣, 它表明我們有我們的Redux 應用建立了我們的 data 致力于全局狀態和我們的視圖組件映射數據。
明天, 我們將開始通過操作創建者來觸發我們的全局狀態的更新, 并通過將多個redux模塊組合在一起來工作。
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/84723.html
摘要:今天我們將討論創建組件的最終方案,即無狀態函數的純組件。今天我們正在研究一種處理提出的復雜數據的方法,稱為體系結構。第天部署介紹今天,我們將探討部署我們的應用所涉及的不同部分,以便外界可以使用我們的應用。 本文轉載自:眾成翻譯譯者:iOSDevLog鏈接:http://www.zcfy.cc/article/3758原文:https://www.fullstackreact.com/3...
摘要:在方法中處理數據有三不同的角色派發器儲存視圖層我們的組件的主要思想是有一個單一源儲存他們只能通過觸發更新。這些操作負責調用派發器可以訂閱更改并相應地更新自己的數據。與不同不使用派發器而是使用純函數來定義數據變異函數。 本文轉載自:眾成翻譯譯者:iOSDevLog鏈接:http://www.zcfy.cc/article/3812原文:https://www.fullstackreact...
摘要:去營救有一種方法我們把我們的歸約器分成多個歸約器每個都只負責狀態樹的葉子。此外我們還學習了如何擴展以使用多個歸約器和動作以及多個連接的組件。 本文轉載自:眾成翻譯譯者:iOSDevLog鏈接:http://www.zcfy.cc/article/3825原文:https://www.fullstackreact.com/30-days-of-react/day-20/ 使用Redux,...
摘要:本文轉載自眾成翻譯譯者鏈接原文今天,我們在方法中使用中間件來管理我們的代碼中的復雜狀態變化。中間件是一個很好的地方。我們中間件我們將實現一些中間件它將代表我們處理異步請求。中間件位于動作和歸并器之間。讓我們創建我們的第一個中間件。 本文轉載自:眾成翻譯譯者:iOSDevLog鏈接:http://www.zcfy.cc/article/3810原文:https://www.fullsta...
摘要:包包含由團隊提供的測試實用程序。將在一個名為的目錄中自動查找整個樹中的測試文件是的帶有下劃線。讓我們為時間軸組件創建第一個測試。其中之一是命令。現在我們已經編寫了第一個測試并確認了我們的設置我們將在明天開始測試我們的時間軸組件。 本文轉載自:眾成翻譯譯者:iOSDevLog鏈接:http://www.zcfy.cc/article/3807原文:https://www.fullstac...
閱讀 1334·2021-09-01 11:40
閱讀 3941·2021-08-05 10:03
閱讀 974·2019-08-30 15:54
閱讀 2816·2019-08-29 12:53
閱讀 3179·2019-08-29 12:23
閱讀 940·2019-08-26 13:45
閱讀 2277·2019-08-26 10:41
閱讀 2535·2019-08-23 16:44