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 storecombineReducers
:合并多个reducerapplyMiddleware:
传入中间件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 进行交互。这大大简化了组件与状态管理之间的关系,提高了代码的可维护性和可扩展性。
总结
以上为个人经验,希望能给大家一个参考,也希望大家多多支持脚本之家。
相关文章
详解Stack Navigator中使用自定义的Render Callback
这篇文章主要为大家介绍了Stack Navigator中使用自定义的Render Callback使用详解,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪2022-10-10
最新评论