react 專案整合 react-redux 解決 state 儲存與共享問題
整理了一下react-redux用法, 備忘一下, 用到時看下就集成了, 方便
redux 裡涉及了兩個東西, action
reduce
, 至於為啥叫這個名字, 我也不知道
action 開發業務邏輯的, reduce是管理狀態的, 它倆是通過 dispatch 物件聯絡上的
action和reduce開發好之後, 又是通過 react-redux 中的 connect 跟元件關聯上的
大致流程就是這樣吧, 具體原理我也不知道, 下面介紹用法, 沒有原理介紹, 想了解原理的, 可以去github上找redux開源專案看readme瞭解
為啥要整合 redux 呢, 好好的 state用的不好麼?
專案大了, 巢狀深了, 通過props傳值就會變的很費勁, 如果有redux幫忙管理這些state, 就方便的多了, 其實redux就是解決state儲存和在元件間共享的問題(我的理解)
建立專案
首先建立react專案
npx create-react-app react-redux-demo
建立好之後, 啟動
yarn start
新增功能
給專案增加一個請求介面的方法, 我這用的是axios, 請求的是 cnodejs.org 的介面, 具體程式碼如下
yarn add axios
import React, { Component } from "react"; import axios from "axios"; import "./App.css"; export default class App extends Component { state = { topics: [] }; componentDidMount() { axios .get("https://cnodejs.org/api/v1/topics") .then(resp => this.setState({ topics: resp.data.data })); } render() { return ( <div> <h1>NodeJS中文</h1> <ul> {this.state.topics.map(item => ( <li key={item.id}> <div className="title">{item.title}</div> </li> ))} </ul> </div> ); } }
原鏈文接: https://tomoya92.github.io/2019/05/13/react-redux/
css
.title { font-size: 18px; font-weight: 500; color: #222; line-height: 1.7; padding: 5px 0; border-bottom: 1px dashed #ccc; }
執行結果
新增redux
安裝依賴
yarn add react-redux redux redux-logger redux-thunk
新增兩個資料夾 actions
reduces
- actions 它裡面主要是寫業務操作的
- reduces 它裡面維護的是state
在actions裡建立一個 test.js
檔案, 新增上獲取話題列表的邏輯
import axios from "axios"; export function fetchTopics(page) { return function(dispatch) { axios .get("https://cnodejs.org/api/v1/topics?page=" + page) .then(resp => dispatch({ type: "FETCH_TOPICS", payload: { topics: resp.data.data } }) ); }; }
然後在 reduces 裡建立一個 test.js
用來維護 App.js
元件的狀態, 具體程式碼如下
export default ( state = { topics: [] }, action ) => { switch (action.type) { case "FETCH_TOPICS": return { ...state, topics: action.payload.topics }; default: return state; } };
再在 reduces 裡建立一個 index.js
用來管理這些 reduces
import { combineReducers } from "redux"; import test from "./test"; export default combineReducers({ app: test });
在src下建立 store.js
檔案, 用來管理 reduces
import {applyMiddleware, createStore} from 'redux'; import {createLogger} from 'redux-logger'; import thunk from 'redux-thunk'; import reduce from './reduces'; const middleware = applyMiddleware(thunk, createLogger()); export default createStore( reduce, // window.__REDUX_DEVTOOLS_EXTENSION__ && window.__REDUX_DEVTOOLS_EXTENSION__(), middleware, );
這裡面還加上了日誌功能
接著修改 src/index.js
檔案, 讓react專案支援 redux, 在 <App/>
外加上 <Provider>
標籤
import React from "react"; import ReactDOM from "react-dom"; import App from "./components/App"; import * as serviceWorker from "./serviceWorker"; import { Provider } from "react-redux"; import store from "./store"; ReactDOM.render( <Provider store={store}> <App /> </Provider>, document.getElementById("root") ); serviceWorker.unregister();
文原連結: https://tomoya92.github.io/2019/05/13/react-redux/
最後在元件中使用, 修改 App.js
的程式碼, 先讓元件跟 redux 連線起來
export default connect(state => { return { app: state.app }; })(App);
然後去掉元件裡的 state
this.props.dispatch(actions裡的方法名()) this.props.app.topics
其中 app 是在 reduces/index.js
裡管理reduce時起的名, topics就是 test.js
裡定義的state
App.js 完整程式碼如下
import React, { Component } from "react"; import "./App.css"; import { connect } from "react-redux"; import { fetchTopics } from "../actions/test"; class App extends Component { componentDidMount() { this.props.dispatch(fetchTopics(1)); } render() { return ( <div> <h1>NodeJS中文</h1> <ul> {this.props.app.topics.map(item => ( <li key={item.id}> <div className="title">{item.title}</div> </li> ))} </ul> </div> ); } } export default connect(state => { return { app: state.app }; })(App);
啟動專案, 效果是一樣的, 這樣就可以給把不同元件的state統一管理了, 在當前元件裡也可以通過連線的方式引入其它元件的state了, 方便
##總結
上面只是介紹了用法,沒有介紹原理, 其實我也不太明白, 感覺跟java後臺寫法差不多, 寫法很固定, 照著抄就行了, 改動的地方非常少
不過它也有不好的地方, 如果網頁重新整理了, 存在redux裡的狀態資料就全沒了
原文連結: