redux和react-redux在項目中的使用

redux和react-redux的區別:

  • reduc可以在各種框架中使用(vue,angular,jquery…),不侷限於react
  • react-redux爲react特定的狀態管理容器,依賴於redux

redux基本使用
在使用react-redux之前先學習下redux的使用redux中文api地址
redux涉及幾個重要部分Action,reducer,store,state,描述如下(粘貼自官網):

Action:是把數據從應用傳到 store 的有效載荷。它是 store 數據的唯一來源。
reducer: 指定了應用狀態的變化如何響應 actions 併發送到 store 的,記住 actions 只是描述了有事情發生了這一事實,並沒有描述應用如何更新 state
store:就是把Action和Reducer聯繫到一起的對象

根據自己理解三者關係圖
在這裏插入圖片描述
組件內部通過store.dispatch(action)將action傳給store,接收的action通過reducer函數來進行邏輯判斷,返回新的store
使用如下:

  1. 確保安裝node,構建項目 npx create-react-app my-app
  2. 安裝redux npm install --save redux
  3. 進入項目 cd my-app,運行 npm start
  4. 刪除不必要的文件,構建項目結構如下
    在這裏插入圖片描述

action/index.js
上面提到過action是一個有效載荷,我的理解是在定義state的時候,把所有的state放到action中,無論是常量還是action創建函數,在需要觸發store狀態變化的時候,從定義的action文件中集中取action對象

export const COLOR_ONE = "color one";
export const COLOR_TWO = "color two";
export function get_des(obj) {
  return { type: "COLOR_DES", title: obj.title, text: obj.text };
}

reducer/index.js
寫reducer函數的時候要先明確自己的state樹結構

import { COLOR_ONE, COLOR_TWO } from "../action";
const initState = {
  COLOR_ONE: COLOR_ONE,
  COLOR_TWO: COLOR_TWO,
  COLOR_OBJ: { title: "default title", text: "default description" }
};
const reducer = (state = initState, action) => {
  console.log("reducer---------", state, action);   //app.js中dispatch後調用reducer函數
  switch (action.type) {
    case "COLOR_DES":
      return Object.assign({}, state, {
        COLOR_OBJ: {
          title: action.title,
          text: action.text
        }
      });
    default:
      return state;
  }
};
export default reducer;

store/index.js

import { createStore } from "redux";
import reducer from "../reducer";
const store = createStore(reducer);
export default store;

app.js

import React from "react";
import store from "./store";
import {get_des} from "./action";
store.dispatch(get_des({title:"App頁面標題",text:"App頁面描述"})); //觸發狀態更改
function App() {
  return (
    <div className="App">
    
    </div>
  );
}

export default App;

運行控制檯輸出如下
在這裏插入圖片描述

可以看到在app.js頁面dispatch的內容在reducer函數中被打印,說明更改狀態成功
在其它組件內可以通過引入store,調用store.getState()方法獲取state

react-redux基本使用
項目構建過程同redux,除了redux外再安裝react-redux npm install react-redux --save
具體使用參見react-redux使用 ,這裏列舉下connect方法的使用

參數名 類型 說明
mapStateToProps(state,ownProps) Function 這個函數允許我們將store中的數據作爲props綁定到組件上
state:redux中的store
ownProps:自己的props
mapDispatchToProps(dispatch,ownProps) Function 將action作爲props綁定到我們自己的函數中
dispatch:store.dispatch()
ownProps:自己的props
mergeProps(stateProps,dispatchProps,ownProps) Function 不管是stateprops還是dispatchprops,都需要和ownprops合併之後才能賦值給組件,通常情況下你可以不傳這個參數,connect就會使用Object.assign替代
options Object 可以定製connector的行爲

app下有兩個子組件分別是Boy和Girl,Boy組件發射愛心,Girl組件接收
react-redux項目目錄結構如下
在這裏插入圖片描述
action/index.js

export function sendAction() {
  return { type: "send_heart" };
}
export function stopSend() {
  return { type: "stop_heart" };
}


reducer/index.js

const initState = {
  status: true
};
const reducer = (state = initState, action) => {
  console.log("reducer------", state);
  switch (action.type) {
    case "send_heart":
      return {
        status: true
      };
    case "stop_heart":
      return {
        status: false
      };
    default:
      return state;
  }
};
export default reducer;

store/index.js

import { createStore } from "redux";
import reducer from "../reducer";
const store = createStore(reducer);
export default store;

boy/index.js

import React, { useState } from "react";
import {sendAction,stopSend}  from "../../action";
import { connect } from "react-redux";
function Boy(props) {
  const send = "send heart";
  const stop = "stop send heart";
  const [status, setStatus] = useState(props.status);
  function changeStatus() {
    status ? props.stop_heart() : props.send_heart();
    setStatus(!status);
  }
  return (
    <>
      <h1>{status ? send : stop}</h1>
      <button onClick={() => changeStatus()}>{status ? stop : send}</button>
    </>
  );
}
const mapStateToProps = state => {
  return state;
};
const mapDispatchToProps = dispatch => {
  return {
    send_heart: () => {
      dispatch(sendAction());
    },
    stop_heart: () => {
      dispatch(stopSend());
    }
  };
};
export default connect(mapStateToProps, mapDispatchToProps)(Boy);

girl/index.js

**import React from "react";
import { connect } from "react-redux";
function Girl(props) {
  console.log(props);
  return (
    <>
      <h1>{props.status?"發送圖片":"停止發送"}</h1>
    </>
  );
}
const mapStateToProps = state => {
  return state;
};
export default connect(mapStateToProps)(Girl);

app.js

import React from "react";
import { Provider } from "react-redux";
import Boy from "./pages/Boy";
import Girl from "./pages/Girl";
import store from "./store";
function App() {
  return (
    <Provider store={store}>
      <div className="App">
        <Boy />
        <Girl />
      </div>
    </Provider>
  );
}

export default App;

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章