成人国产在线小视频_日韩寡妇人妻调教在线播放_色成人www永久在线观看_2018国产精品久久_亚洲欧美高清在线30p_亚洲少妇综合一区_黄色在线播放国产_亚洲另类技巧小说校园_国产主播xx日韩_a级毛片在线免费

資訊專欄INFORMATION COLUMN

React Hooks實現(xiàn)異步請求實例—useReducer、useContext和useEffec

Code4App / 2775人閱讀

摘要:本文是學(xué)習(xí)了年新鮮出爐的提案之后,針對異步請求數(shù)據(jù)寫的一個案例。注意,本文假設(shè)了你已經(jīng)初步了解的含義了,如果不了解還請移步官方文檔。但不要忘記和上下文對象可以看做是寫法的以及三個鉤子函數(shù)的組合。

本文是學(xué)習(xí)了2018年新鮮出爐的React Hooks提案之后,針對異步請求數(shù)據(jù)寫的一個案例。注意,本文假設(shè)了:
1.你已經(jīng)初步了解hooks的含義了,如果不了解還請移步官方文檔。(其實有過翻譯的想法,不過印記中文一直在翻譯,就是比較慢啦)
2.你使用Redux實現(xiàn)過異步Action(非必需,只是本文不涉及該部分知識而直接使用)
3.你聽說過axios或者fetch(如果沒有,那么想象一下原生js的promise實現(xiàn)異步請求,或者去學(xué)習(xí)下這倆庫)
全部代碼參見倉庫: github | Marckon選擇hooks-onlineShop分支以及master分支查看

? 本文并非最佳實踐,如有更好的方法或發(fā)現(xiàn)文中紕漏,歡迎指正!

前序方案(不想看可以直接跳過)

不考慮引入Redux

通過學(xué)習(xí)React生命周期,我們知道適合進(jìn)行異步請求的地方是componentDidMount鉤子函數(shù)內(nèi)。因此,當(dāng)你不需要考慮狀態(tài)管理時,以往的方法很簡單:

class App extends React.Component{
    componentDidMount(){
        axios.get("/your/api")
            .then(res=>/*...*/)
    }
}

引入Redux進(jìn)行狀態(tài)管理

當(dāng)你決定使用Redux進(jìn)行狀態(tài)管理時,比如將異步獲取到的數(shù)據(jù)儲存在store中,事情就開始復(fù)雜起來了。根據(jù)Redux的官方文檔案例來看,為了實現(xiàn)異步action,你還得需要一個類似于redux-thunk的第三方庫來解析你的異步action

requestAction.js: 定義異步請求action的地方

//這是一個異步action,分發(fā)了兩個同步action,redux-thunk能夠理解它
const fetchGoodsList = url => dispatch => {
    dispatch(requestGoodsList());
    axios.get(url)
        .then(res=>{
            dispatch(receiveGoodsList(res.data))
        })
};

requestReducer.js: 處理同步action

const requestReducer=(state=initialState,action)=>{
    switch (action.type) {
        case REQUEST_GOODSLIST:
            return Object.assign({},state,{
                isFetching: true
            });
        case RECEIVE_GOODSLIST:
            return Object.assign({},state,{
                isFetching:false,
                goodsList:action.goodsList
            });
        default:
            return state;
    }
};

App Component :你引入redux store和redux-thunk中間件的地方

import {Provider} from "react-redux";
import thunkMiddleWare from "redux-thunk";
import {createStore,applyMiddleware} from "redux";
//other imports

let store=createStore(
    rootReducer,
    //這里要使用中間件,才能夠完成異步請求
    applyMiddleware(
        thunkMiddleWare,
        myMiddleWare,

    )
);
class App extends React.Component{
    render(){
        return (
            
                
            
        )
    }
}

GoodsList Component :需要進(jìn)行異步請求的組件

class GoodsList extends React.Component{
    //...
    componentDidMount(){
        this.props.fetchGoodsList("your/url");
    }
    //...
}
const mapDispatchToProps={
    fetchGoodsList
}
export default connect(
    mapStateToProps,
    mapDispatchToProps
)(GoodsList);

完整代碼:branch:master-onlineShop

使用Hooks-useReducer()useContext()

總之使用Redux很累,當(dāng)然,你可以不使用Redux,直接通過props層層傳遞,或者使用context都可以。只不過本文我們學(xué)過了useReducer,使用到了Redux的思想,總要試著用一下。

這里你不需要引入別的任何第三方庫了,簡簡單單地使用[email protected]版本就好啦

很重要的一點就是——函數(shù)式組件,現(xiàn)在React推薦我們這么做,可以基本上代替class寫法。

函數(shù)簽名

useReducer(reducer,initialState)

useContext(ctxObj)

useEffect(effectFunction,[dependencyValues])

概覽-你需要編寫什么

action.js:

我們還使用redux的思想,編寫action

reducer.js:

處理action,不同于reduxreducer,這里我們可以不用提供初始狀態(tài)

根組件:

Provider提供給子組件context

useReducer定義的位置,引入一個reducer并且提供初始狀態(tài)initialState

子組件:

useContext定義的位置,獲取祖先組件提供的context

useEffect用于進(jìn)行異步請求

實現(xiàn) 1.action.js:我們使用action創(chuàng)建函數(shù)
const REQUEST_GOODSLIST = "REQUEST_GOODSLIST";
const RECEIVE_GOODSLIST = "RECEIVE_GOODSLIST";

//開始請求
const requestGoodsList = () => ({
    type: REQUEST_GOODSLIST
});

//接收到數(shù)據(jù)
const receiveGoodsList = json => ({
    type: RECEIVE_GOODSLIST,
    goodsList: json.goodsList,
    receivedAt: Date.now()
});

export {
    RECEIVE_GOODSLIST,
    REQUEST_GOODSLIST,
    receiveGoodsList,
    requestGoodsList,
}
2.reducer.js:判斷action的類型并進(jìn)行相應(yīng)處理,更新state
import {
    RECEIVE_GOODSLIST,
    REQUEST_GOODSLIST,
} from "../..";


export const fetchReducer=(state,action)=>{
    switch (action.type) {
        case REQUEST_GOODSLIST:
            return Object.assign({},state,{
                isFetching: true
            });
        case RECEIVE_GOODSLIST:
            return Object.assign({},state,{
                isFetching:false,
                goodsList:state.goodsList.concat(action.goodsList)
            });
        default:
            return state;
    }
};

3.根組件:引入reducer.js
import React,{useReducer} from "react";
import {fetchReducer} from "..";

//創(chuàng)建并export上下文
export const FetchesContext = React.createContext(null);

function RootComponent() {
    //第二個參數(shù)為state的初始狀態(tài)
    const [fetchesState, fetchDispatch] = useReducer(fetchReducer, {
            isFetching: false,
            goodsList: []
        });
    return (
        //將dispatch方法和狀態(tài)都作為context傳遞給子組件
         
             //...
             //用到context的一個子組件
             
         
    )
}
4.子組件:引入FetchesContext
import {FetchesContext} from "../RootComponent";
import React, {useContext, useEffect,useState} from "react";
import axios from "axios";

function GoodsList() {

    //獲取上下文
    const ctx = useContext(FetchesContext);
    
    //一個判斷是否重新獲取的state變量
    const [reFetch,setReFetch]=useState(false);

    //具有異步調(diào)用副作用的useEffect
    useEffect(() => {
        //首先分發(fā)一個開始異步獲取數(shù)據(jù)的action
        ctx.dispatch(requestGoodsList());
            axios.get(proxyGoodsListAPI())
                .then(res=>{
                    //獲取到數(shù)據(jù)后分發(fā)一個action,通知reducer更新狀態(tài)
                    ctx.dispatch(receiveGoodsList(res.data))
                })
      //第二個參數(shù)reFetch指的是只有當(dāng)reFetch變量值改變才重新渲染
    },[reFetch]);

    return (
        
{ //children }
) }

完整代碼參見:branch:hooks-onlineShop

目錄結(jié)構(gòu)

我的目錄結(jié)構(gòu)大概這樣:

src
  |- actions
     |- fetchAction.js
  |- components
     |-...
  |- reducers
     |- fetchReducer.js
  |- index.js
注意點

使用useContext()時候我們不需要使用Consumer了。但不要忘記exportimport上下文對象

useEffect()可以看做是class寫法的componentDidMount、componentDidUpdate以及componentWillUnMount三個鉤子函數(shù)的組合。

當(dāng)返回了一個函數(shù)的時候,這個函數(shù)就在compnentWillUnMount生命周期調(diào)用

默認(rèn)地,傳給useEffect的第一個參數(shù)會在每次(包含第一次)數(shù)據(jù)更新時重新調(diào)用

當(dāng)給useEffect()傳入了第二個參數(shù)(數(shù)組類型)的時候,effect函數(shù)會在第一次渲染時調(diào)用,其余僅當(dāng)數(shù)組中的任一元素發(fā)生改變時才會調(diào)用。這相當(dāng)于我們控制了組件的update生命周期

useEffect()第二個數(shù)組為空則意味著僅在componentDidMount周期執(zhí)行一次

代碼倉庫里使用了Mock.js攔截api請求以及ant-design第三UI方庫。目前代碼比較簡陋。

文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請注明本文地址:http://systransis.cn/yun/99617.html

相關(guān)文章

  • 使用react hooks實現(xiàn)自己的context-redux

    摘要:首發(fā)自我的博客,歡迎注如要運行本文的代碼,請先確認(rèn)自己的版本已支持出來已經(jīng)有段時間了,本文不對的具體用法作介紹,而是使用實現(xiàn)一個簡易的基于的使用實現(xiàn)初版自帶了供我們使用,它接受兩個參數(shù),一是函數(shù),二是初始,并返回和函數(shù),如下這個函數(shù)自己實現(xiàn) 首發(fā)自我的github博客,歡迎star 注:如要運行本文的代碼,請先確認(rèn)自己的react版本已支持hooks react hooks出來已經(jīng)有段...

    Jackwoo 評論0 收藏0
  • 精讀《Function Component 入門》

    摘要:比如就是一種,它可以用來管理狀態(tài)返回的結(jié)果是數(shù)組,數(shù)組的第一項是值,第二項是賦值函數(shù),函數(shù)的第一個參數(shù)就是默認(rèn)值,也支持回調(diào)函數(shù)。而之所以輸出還是正確的,原因是的回調(diào)函數(shù)中,值永遠(yuǎn)指向最新的值,因此沒有邏輯漏洞。 1. 引言 如果你在使用 React 16,可以嘗試 Function Component 風(fēng)格,享受更大的靈活性。但在嘗試之前,最好先閱讀本文,對 Function Com...

    Scholer 評論0 收藏0
  • 十個案例學(xué)會 React Hooks

    摘要:在線傳遞給的是而不是,返回值即是想要透傳的數(shù)據(jù)了。所以函數(shù)組件在每次渲染的時候如果有傳遞函數(shù)的話都會重渲染子組件。在學(xué)會使用React Hooks之前,可以先看一下相關(guān)原理學(xué)習(xí)React Hooks 前言 在 React 的世界中,有容器組件和 UI 組件之分,在 React Hooks 出現(xiàn)之前,UI 組件我們可以使用函數(shù),無狀態(tài)組件來展示 UI,而對于容器組件,函數(shù)組件就顯得無能為力,我...

    williamwen1986 評論0 收藏0
  • React Hooks入門: 基礎(chǔ)

    摘要:當(dāng)組件安裝和更新時,回調(diào)函數(shù)都會被調(diào)用。好在為我們提供了第二個參數(shù),如果第二個參數(shù)傳入一個數(shù)組,僅當(dāng)重新渲染時數(shù)組中的值發(fā)生改變時,中的回調(diào)函數(shù)才會執(zhí)行。 前言   首先歡迎大家關(guān)注我的Github博客,也算是對我的一點鼓勵,畢竟寫東西沒法獲得變現(xiàn),能堅持下去也是靠的是自己的熱情和大家的鼓勵,希望大家多多關(guān)注呀!React 16.8中新增了Hooks特性,并且在React官方文檔中新增...

    mrli2016 評論0 收藏0

發(fā)表評論

0條評論

最新活動
閱讀需要支付1元查看
<