Redux使用方法和基本原理解读

 更新时间:2023年10月07日 14:13:32   作者:音仔小瓜皮  
这篇文章主要介绍了Redux使用方法和基本原理,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教

一、redux core和redux tookit

1、区别

redux core是最原生的redux概念,其优点是可定制性好,缺点是什么都要自己写。主要思想是通过传入createStore,将actions、reducers、middlewares等进行自己配置。

redux toolkit其实是去包裹一个redux core的工具集,引入了一些简化的 API去配置redux store。同时Redux Toolkit 中的 createSlice 自动生成了每个 reducer case 对应的 action creators,免去了手动编写 action creators 的繁琐步骤。不仅如此,redux toolkit还默认集成了redux-thunk中间件。避免了每次都要手动配置。

2、基本配置和使用

1、redux core

基本api:

  • createStore  :创建一个redux store
  • combineReducers  :合并多个reducer
  • applyMiddleware:传入中间件
  • compose :合并多个store

当你配置某个store在store.js文件中、reducer定义在reducers.js文件中、并且引入一些middleware时,配置方法大致为:

//store.js
import { createStore, applyMiddleware } from 'redux';
import rootReducer from './reducers';
import thunkMiddleware from 'redux-thunk'; // Redux Thunk 中间件
import loggerMiddleware from 'redux-logger'; // Redux Logger 中间件
const middlewares = [thunkMiddleware, loggerMiddleware]; // 定义要使用的中间件数组
const store = createStore(
  rootReducer,
  applyMiddleware(...middlewares) // 将中间件数组展开并应用到 Redux Store
);
export default store;
//reducers.js
import { combineReducers } from 'redux';
import counterReducer from './counterReducer';
import userReducer from './userReducer';
// 合并多个 reducer
const rootReducer = combineReducers({
  counter: counterReducer,
  user: userReducer
});
export default rootReducer;
//counterReducer.js
export function counterReducer(state = { value: 0 }, action) {
  switch (action.type) {
    case 'counter/incremented':
      return { value: state.value + 1 }
    case 'counter/decremented':
      return { value: state.value - 1 }
    default:
      return state
  }
}
//dispatch传入action对象
//store.dispatch({ type: 'counter/incremented' })
// {value: 1}
//store.dispatch({ type: 'counter/incremented' })
// {value: 2}
//store.dispatch({ type: 'counter/decremented' })

2、redux toolkit

在slice.js中创建reducers、在store.js中创建store并配置reducers和中间件

//store.js
import { configureStore } from '@reduxjs/toolkit'
import todosReducer from '../features/todos/todosSlice'
import filtersReducer from '../features/filters/filtersSlice'
export const store = configureStore({
  reducer: {
    todos: todosReducer,
    filters: filtersReducer
  }
})

在slice中,只需要直接定义reducers操作而无需再对action creators即{type :  actions.type}对象做出显示创建或定义,其放入dispatch中会自动创建、分发

//slice.js,导出actions和reducers
import { createSlice } from '@reduxjs/toolkit'
const todosSlice = createSlice({
  name: 'todos',
  initialState: [],
  reducers: {
    todoAdded(state, action) {
      state.push({
        id: action.payload.id,
        text: action.payload.text,
        completed: false
      })
    },
    todoToggled(state, action) {
      const todo = state.find(todo => todo.id === action.payload)
      todo.completed = !todo.completed
    }
  }
})
export const { todoAdded, todoToggled } = todosSlice.actions
export default todosSlice.reducer

二、dispatch action修改store

  • dispatch 同步的操作。当你调用 Redux Store 的
  • dispatch 方法分发一个 action 时,Redux 会立即执行 reducer 并更新状态。这意味着
  • dispatch 操作本身不会引起异步行为。

在组件中,我们可以用useDispatch hook来获取到dispatch方法,从而对store进行操作

三、reducer

Reducer 是同步的

在 Redux 中,Reducer 是一个纯函数,负责处理分发的 action 并更新状态。

它是一个纯粹的函数,不应该包含任何副作用,如异步操作、网络请求等。

四、middleware中间件

1、常用中间件 redux-thunk

  • redux-thunk

是一个 Redux 中间件,它允许你在 action creators 中返回函数而不仅仅是普通的 action 对象。

这个函数可以用于处理异步操作,如发起网络请求、定时器、以及其他需要延迟执行的操作。

在 Redux 中,普通的 action 必须是一个普通的对象,包含一个 type 属性来描述操作的类型。

有些情况下,我们需要在 action creators 中执行异步操作,例如从服务器获取数据,然后再将相应的数据分发到 Redux Store 中。

这就是 redux-thunk 发挥作用的地方。

redux-thunk 的主要功能是拦截分发的 action,dispatch中可以接受对象也可以接受函数,并判断 action 是一个普通的对象还是一个函数。

如果是一个函数, redux-thunk 会将 dispatch getState 函数传递给这个函数,使得你可以在函数内部执行异步操作,并在操作完成后手动分发其他 action。

*用法示例:

import { createStore, applyMiddleware } from 'redux';
import thunkMiddleware from 'redux-thunk';
import rootReducer from './reducers';
const store = createStore(
  rootReducer,
  applyMiddleware(thunkMiddleware)
);
// 异步 action creator
function fetchData() {
  return (dispatch, getState) => {
    // 获取当前 Redux store 状态
    const currentState = getState();
    // 执行异步操作
    fetch('https://api.example.com/data')
      .then(response => response.json())
      .then(data => {
        // 在异步操作完成后使用 dispatch 函数将请求结果传递给 Redux store
        dispatch({ type: 'FETCH_DATA_SUCCESS', payload: data });
      });
  };
}
store.dispatch(fetchData()); // 分发异步 action
  • redux-saga

创建一个 Saga,它是一个 Generator 函数,用于处理特定的异步操作。

Saga 监听 action 并执行相应的逻辑。

你可以在 Saga 中执行异步操作,如网络请求、定时器等。

// sagas.js
import { takeEvery, put, call } from 'redux-saga/effects';
import { FETCH_DATA, fetchDataSuccess, fetchDataFailure } from './actions';
function* fetchDataSaga(action) {
  try {
    const response = yield call(fetch, 'https://api.example.com/data');
    const data = yield call([response, 'json']);
    yield put(fetchDataSuccess(data));
  } catch (error) {
    yield put(fetchDataFailure(error));
  }
}
export function* rootSaga() {
  yield takeEvery(FETCH_DATA, fetchDataSaga);
}

创建saga middleware放入到store中

// store.js
import { createStore, applyMiddleware } from 'redux';
import createSagaMiddleware from 'redux-saga';
import rootReducer from './reducers';
import { rootSaga } from './sagas';
const sagaMiddleware = createSagaMiddleware();
const store = createStore(
  rootReducer,
  applyMiddleware(sagaMiddleware)
);
sagaMiddleware.run(rootSaga);
export default store;
  • redux-logger
const loggerMiddleware = createLogger();

每当你调用 action creator 时, redux-logger 会在浏览器控制台中输出相应的日志,显示 action 的类型、旧状态、新状态等信息。

总之, redux-logger 是一个方便的中间件,用于在开发环境中输出有关 Redux 操作的日志,以帮助你更好地理解应用程序的状态变化。

2、自定义中间件

重要的入参:store、next、action

next 是一个函数,用于将 action 继续传递给下一个中间件或最终到达 reducer。

在中间件函数中,你可以执行一些逻辑,然后调用 next(action) 来将 action 传递给下一个中间件或 reducer。

例子:

const myMiddleware = store => next => action => {
  // 在 action 被分发到 reducer 前执行的逻辑
  console.log('Middleware triggered:', action);
  // 将 action 传递给下一个中间件或 reducer
  const result = next(action);
  // 在 action 被分发到 reducer 后执行的逻辑
  console.log('Middleware completed:', action);
  return result;
};

五、一些其他常用方法:(subscribe、connect等等)

1、subscribe

在 Redux 中, subscribe 是一个用于订阅状态变化的方法。

它允许你注册一个回调函数,当 Redux Store 中的状态发生变化时,这个回调函数会被调用,从而你可以执行一些操作来响应状态的变化。

具体来说, subscribe 方法的作用是将一个函数添加到状态变化的监听器列表中,每当状态发生变化时,所有订阅了这个监听器的函数都会被调用。

这样,你可以在状态变化时更新用户界面、执行特定操作等。

store.subscribe(() => console.log(store.getState()))

在上面的例子中, store.subscribe() 方法用于注册一个监听器,每当状态发生变化时,回调函数会被调用并输出当前的状态。通过调用 unsubscribe() 方法,可以取消订阅状态变化,以避免不再需要的监听器持续执行。

总而言之, subscribe 方法在 Redux 中用于监听状态的变化,以便你可以在状态更新时执行相应的操作,如更新界面或触发其他逻辑。

2、connect

connect 是 React Redux 库提供的一个高阶函数(Higher-Order Function),用于连接 React 组件与 Redux Store。它的作用是将 Redux 的状态(state)和操作(actions)与 React 组件进行关联,使得组件能够访问 Redux 中的状态并调用相应的操作来更新状态。

使用 connect 方法,你可以将 Redux Store 中的状态映射到组件的 props 上,以便在组件内部可以直接访问这些状态。同时,你也可以将 Redux 的 Action Creators 映射到组件的 props 上,使得组件可以触发这些操作来分发 action,从而更新 Redux Store 的状态。

connect 方法的基本语法如下:

import { connect } from 'react-redux';
// Connect the component to Redux
const ConnectedComponent = connect(mapStateToProps, mapDispatchToProps)(Component);

其中, mapStateToProps mapDispatchToProps 是两个函数,用于定义如何将 Redux 的状态和操作映射到组件的 props 上。它们的作用分别如下:

  • mapStateToProps(state, ownProps) :这个函数用于将 Redux 的状态映射到组件的 props 上。它接收当前的 Redux 状态作为参数,然后返回一个对象,这个对象中的键值对会成为组件的 props。这样,组件就可以通过 props 直接访问 Redux 中的状态。
  • mapDispatchToProps(dispatch, ownProps):这个函数用于将 Redux 的 Action Creators 映射到组件的 props 上。它接收 Redux 的 dispatch 方法作为参数,然后返回一个对象,这个对象中的键值对通常是调用 Action Creators 后返回的 action 对象。这样,组件就可以通过 props 调用这些操作来分发 action。

通过 connect 方法,你可以实现将 Redux 的状态和操作传递给组件,使得组件能够与 Redux Store 进行交互。这大大简化了组件与状态管理之间的关系,提高了代码的可维护性和可扩展性。

总结

以上为个人经验,希望能给大家一个参考,也希望大家多多支持脚本之家。

相关文章

  • windows下create-react-app 升级至3.3.1版本踩坑记

    windows下create-react-app 升级至3.3.1版本踩坑记

    这篇文章主要介绍了windows下create-react-app 升级至3.3.1版本踩坑记,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2020-02-02
  • React Fiber树的构建和替换过程讲解

    React Fiber树的构建和替换过程讲解

    React Fiber树的创建和替换过程运用了双缓存技术,直接将旧的 fiber 树替换成新的 fiber 树,这样做的好处是省去了直接在页面上渲染时的计算时间,避免计算量大导致的白屏、卡顿,现在你一定还不太理解,下面进行详细讲解,需要的朋友可以参考下
    2022-12-12
  • React+Redux实现简单的待办事项列表ToDoList

    React+Redux实现简单的待办事项列表ToDoList

    这篇文章主要为大家详细介绍了React+Redux实现简单的待办事项列表ToDoList,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2019-09-09
  • react echarts tree树图搜索展开功能示例详解

    react echarts tree树图搜索展开功能示例详解

    这篇文章主要为大家介绍了react echarts tree树图搜索展开功能示例详解,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2023-01-01
  • React实现点击删除列表中对应项

    React实现点击删除列表中对应项

    本文主要介绍了React 点击删除列表中对应项的方法。具有一定的参考价值,下面跟着小编一起来看下吧
    2017-01-01
  • 详解React中函数式组件与类组件的不同

    详解React中函数式组件与类组件的不同

    React 函数式组件与类组件的主要区别在于它们的定义和声明方式以及它们之间的一些特性,所以本文就详细的给大家讲讲React中函数式组件与类组件有何不同,需要的朋友可以参考下
    2023-09-09
  • ForwardRef useImperativeHandle方法demo

    ForwardRef useImperativeHandle方法demo

    这篇文章主要为大家介绍了ForwardRef useImperativeHandle方法demo,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2023-03-03
  • 在 React 项目中全量使用 Hooks的方法

    在 React 项目中全量使用 Hooks的方法

    这篇文章主要介绍了在 React 项目中全量使用 Hooks,使用 Hooks 能为开发提升不少效率,但并不代表就要抛弃 Class Component,依旧还有很多场景我们还得用到它,本文给大家介绍的非常详细,需要的朋友可以参考下
    2022-10-10
  • React Native实现Toast轻提示和loading效果

    React Native实现Toast轻提示和loading效果

    这篇文章主要介绍了React Native实现Toast轻提示和loading效果,本文通过实例代码给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2023-09-09
  • 在create-react-app中使用css modules的示例代码

    在create-react-app中使用css modules的示例代码

    这篇文章主要介绍了在create-react-app中使用css modules的示例代码,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2018-07-07

最新评论