redux、react-redux、redux-thunk、redux-saga、@reduxjs/toolkit理解与使用,区别与使用场景?

文章详细介绍了Redux的状态管理机制,包括如何创建store、使用action和reducer,以及如何通过react-redux将Redux与React结合。同时,对比了redux-thunk和redux-saga这两个处理异步操作的中间件,解释了它们的工作原理和使用场景。还提到了@reduxjs/toolkit作为简化Redux开发的工具集,旨在减少样板代码并提高开发效率。
摘要由CSDN通过智能技术生成

1.redux

理解

Redux的核心概念其实很简单:将需要修改的state都存入到store里,发起一个action用来描述发生了什么,用reducers描述action如何改变state tree 。创建store的时候需要传入reducer,真正能改变store中数据的是store.dispatch API。

使用

  • src下新建store文件夹,新建index.js作为store的输出文件
  • store文件夹下新建index.js文件
  • 新建reducer.js ,actionTypes.js文件
  • actionTypes文件夹的作用是存放常量名
    在这里插入图片描述
  • 在组件中引入store
import React, { Component } from 'react';
import { Input ,Button,List } from 'antd';
import store from './store';
import {CHANGE_INPUT_VALUE,ADD_TODO_ITEM,DELETE_TODO_ITEM} from  './store/actionTypes'
class TodoList extends Component {
   constructor(props) {
       super(props);
       this.state = store.getState();
       this.handleStoreChange = this.handleStoreChange.bind(this);
       this.handleBtnClick = this.handleBtnClick.bind(this);
       this.handleInputChange = this.handleInputChange.bind(this);
       store.subscribe(this.handleStoreChange)
   }

   handleInputChange(e) {
       const action = {
           type: CHANGE_INPUT_VALUE,
           value: e.target.value
       }
       store.dispatch(action)
   }

   handleBtnClick() {
       const action = {
           type: ADD_TODO_ITEM
       }
       store.dispatch(action)
   }

   render() {
       return (
           <div style={{marginTop:'20px',marginLeft:'15px'}}>
               <div>
                   <Input
                       value={this.state.inputValue}
                       placeholder="input"
                       style={{width:'300px'}}
                       onChange={this.handleInputChange}
                   />
                   <Button onClick={this.handleBtnClick} type="primary">Primary</Button>
               </div>
               <List
                   style={{marginTop:'15px',width:'300px'}}
                   bordered
                   dataSource={this.state.list}
                   renderItem={(item,index) => <List.Item onClick={this.handleItemDelete.bind(this,index)}>{item}</List.Item>}
                   />
           </div>
       )
   }

   handleStoreChange() {
       this.setState(store.getState())
   }
   handleItemDelete(index) {
       const action = {
           type: DELETE_TODO_ITEM,
           index
       }
       store.dispatch(action)
   }
}

export default TodoList;
  • 在store下的index中使用redux-devtool
import { createStore } from 'redux';
import reducer from './reducer'
 
const store = createStore(
    reducer,
    window.__REDUX_DEVTOOLS_EXTENSION__ && window.__REDUX_DEVTOOLS_EXTENSION__()
);
 
export default store;
  • actionTypes.js代码如下
export const  CHANGE_INPUT_VALUE = 'change_input_value';
export const  ADD_TODO_ITEM = 'add_todo_item';
export const  DELETE_TODO_ITEM = 'delete_todo_item';
  • reducer.js代码如下
import {CHANGE_INPUT_VALUE,ADD_TODO_ITEM,DELETE_TODO_ITEM} from  './actionTypes'
const defaultState = {
   inputValue:'aaa',
   list:['1','2']
}

export default (state = defaultState,action) => {
   if(action.type === CHANGE_INPUT_VALUE) {
       const newState = JSON.parse(JSON.stringify(state));
       newState.inputValue = action.value;
       return newState;
   }
   if(action.type === ADD_TODO_ITEM) {
       const newState = JSON.parse(JSON.stringify(state));
       newState.list.push(newState.inputValue);
       newState.inputValue = '';
       return newState;
   }
   if(action.type === DELETE_TODO_ITEM) {
       const newState = JSON.parse(JSON.stringify(state));
       newState.list.splice(action.index,1);
       return newState;
   }
   return state;
}
  • 优化:使用actionCreactor.js来统一管理action
    在这里插入图片描述

2.react-redux

理解

React-Redux是Redux的官方React绑定库。它能够使你的React组件从Redux store中读取数据,并且向store分发actions以更新数据。

使用

1.在入口文件index.js里引入react-redux及store

import React from 'react';
import ReactDOM from 'react-dom';
import 'antd/dist/antd.css';
import './index.css';
import App from './TodoList';
import * as serviceWorker from './serviceWorker';
import store from './store'
import { Provider } from 'react-redux';
 
const ProviderApp = (
    <Provider store={store}>
        <App></App>
    </Provider>
)
 
ReactDOM.render(ProviderApp, document.getElementById('root'));
serviceWorker.unregister();

2.在组件里做connect

import React, { Component } from 'react';
import { Input ,Button,List } from 'antd';
import {CHANGE_INPUT_VALUE,ADD_TODO_ITEM} from  './store/actionTypes'
import {connect} from 'react-redux';
 
class TodoList extends Component {
    render() {
        const {handleInputChange,handleBtnClick} = this.props
        return (
            <div style={{marginTop:'20px',marginLeft:'15px'}}>
                <div>
                    <Input
                        value={this.props.inputValue}
                        placeholder="input"
                        style={{width:'300px'}}
                        onChange={handleInputChange}
                    />
                    <Button onClick={handleBtnClick} type="primary">Primary</Button>
                </div>
                <List
                    style={{marginTop:'15px',width:'300px'}}
                    bordered
                    dataSource={this.props.list}
                    renderItem={(item,index) => <List.Item>{item}</List.Item>}
                    />
            </div>
        )
    }
 
}
const mapStateToProps = (state) => {
    return {
        inputValue: state.inputValue,
        list : state.list
    }
}
 
const mapDispatchToProps = (dispatch) => {
    return {
        handleInputChange(e) {
            const action = {
                type: CHANGE_INPUT_VALUE,
                value: e.target.value
            }
            dispatch(action)
        },
        handleBtnClick() {
            const action = {
                type: ADD_TODO_ITEM
            }
            dispatch(action)
        },
    }
}
 
export default connect(mapStateToProps,mapDispatchToProps)(TodoList);

3.说一下redux和react-redux的区别:

redux是react中进行state状态管理的JS库,一般是管理多个组件中共享数据的,它并不是react的插件,是一个独立的库vue和angular等等一些框架都是可以使用的。

React-Redux是Redux的官方React绑定库。它能够使你的React组件从Redux store中读取数据,并且向store分发actions以更新数据。

4.说说你对@reduxjs/toolkit的理解?和react-redux有什么区别?

理解:

ReduxToolkit的目的是:在成为编写Redux逻辑的标准方法。

它最初是为了帮助解决关于Redux的三个常见问题而创建的:
1.“配置Redux存储太复杂”
2.“我必须添加很多软件包来让Redux做任何有用的事情
3.“Redux需要太多的样板代码”

我们不能解决每一个用例,但本着创建-反应-应用的精神,我们可以尝试提供一些抽象的设置过程和处理最常见的用例的工具,以及包括一些有用的实用程序,让用户简化他们的应用程序代码。

ReduxToolkit还包括一个强大的数据获取和缓存功能,我们称之为“RTK查询”。它作为一组单独的入口点包含在软件包中。它是可选的,但可以消除手工编写数据获取逻辑的需要。

这些工具应该是有益的所有Redux用户。无论你是一个全新的Redux用户设置你的第一个项目,还是一个有经验的用户谁想要简化现有的应用程序,Redux工具包可以使我们的的Redux代码更好。

区别

  • react-redux 是react官方推出的redux绑定库,react-redux将所有组件分为两大类:UI组件和容器组件,其中所有容器组件包裹着UI组件,构成父子关系。容器组件负责和redux交互,里面使用redux API函数,UI组件负责页面渲染,不使用任何redux API。容器组件会给UI组件传递redux中保存对的状态和操作状态的方法
  • @reduxjs/toolkit 是Redux 官方强烈推荐,开箱即用的一个高效的 Redux 开发工具集。它旨在成为标准的 Redux 逻辑开发模式,使用 Redux Toolkit 都可以优化你的代码,使其更可维护

5.redux-thunk使用

理解:中间件的概念

dispatch一个action之后,到达reducer之前,进行一些额外的操作,就需要用到middleware。
可以利用 Redux middleware 来进行日志记录、创建崩溃报告、调用异步接口或者路由等等。
换言之,中间件都是对store.dispatch()的增强。redux-thunk就是用来异步操作,比如接口请求等。

当我们返回的是函数时,store会帮我们调用这个返回的函数,并且把dispatch暴露出来供我们使用。对于redux-thunk的整个流程来说,它是等异步任务执行完成之后,我们再去调用dispatch,然后去store去调用reduces

使用

  • 引入redux-thunk
import { applyMiddleware, createStore } from 'redux';
import thunk from 'redux-thunk';
 const store = createStore(
  reducers,
  applyMiddleware(thunk)
);
  • 在actionCreactor中创建一个带异步函数的方法了
export const getTodoList = () => {
    return () => {
        axios.get('./list').then((res)=>{
            const data = res.data;
            const action  = initListAction(data);
            StorageEvent.dispatch(action);
        })
    }
}

6.redux-saga使用

理解

redux-saga是一个用于管理redux应用异步操作的中间件,redux-saga通过创建sagas将所有异步操作逻辑收集在一个地方集中处理,可以用来代替redux-thunk中间件。
  
当我们dispatch的action类型不在reducer中时,redux-saga的监听函数takeEvery就会监听到,等异步任务有结果就执行put方法,相当于dispatch,再一次触发dispatch。对于redux-saga的整个流程来说,它是等执行完action和reducer之后,判断reducer中有没有这个action

使用

在store.js里引入redux-saga

import { createStore, applyMiddleware } from 'redux'
import createSagaMiddleware from 'redux-saga'
 
import reducer from './reducers'
import mySaga from './sagas'
 
// create the saga middleware
const sagaMiddleware = createSagaMiddleware()
// mount it on the Store
const store = createStore(
  reducer,
  applyMiddleware(sagaMiddleware)
)
 
// then run the saga
sagaMiddleware.run(mySaga)export default store

新建 saga.js

import { call, put, takeEvery, takeLatest } from 'redux-saga/effects'
import Api from '...'
 
// worker Saga: will be fired on USER_FETCH_REQUESTED actions
function* fetchUser(action) {
   try {
      const user = yield call(Api.fetchUser, action.payload.userId);
      yield put({type: "USER_FETCH_SUCCEEDED", user: user});
   } catch (e) {
      yield put({type: "USER_FETCH_FAILED", message: e.message});
   }
}
function* mySaga() {
  yield takeEvery("USER_FETCH_REQUESTED", fetchUser);
}
 
export default mySaga;

7. redux-saga和redux-thunk的区别和使用场景

区别

qubie redux-thunk和redux-saga处理异步任务的时机不一样。
对于redux-saga,相对于在redux的action基础上,重新开辟了一个 async action的分支,单独处理异步任务。
saga 自己基本上完全弄了一套 asyc 的事件监听机制,代码量大大增加

从使用体验来看 redux-thunk 更简单,和 redux 本身联系地更紧密。尤其是整个生态都向函数式编程靠拢的今天,redux-thunk 的高阶函数看上去更加契合这个闭环。

使用场景

redux-thunk

在dispatch一个action之后,到达reducer之前,进行一些额外的操作,就需要用到middleware。中间件都是对store.dispatch()的增强。
我们可以利用 Redux middleware 来进行日志记录、创建崩溃报告、调用异步接口或者路由等等。
redux-thunk就是用来异步操作,比如接口请求等。

redux-saga

redux-saga是一个用于管理redux应用异步操作的中间件,redux-saga通过创建sagas将所有异步操作逻辑收集在一个地方集中处理,可以用来代替redux-thunk中间件。
通过定义saga函数进行监控,同时提供一些常用的API

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值