或许你当前的项目还没有到应用 Redux 的程度, 但提前了解一下也没有坏处
首先我们会用到哪些框架和工具呢?
React
UI 框架
Redux
状态管理工具, 与 React 没有任何关系, 其他 UI 框架也可以使用 Redux
react-redux
React 插件, 作用: 方便在 React 项目中使用 Redux
react-thunk
中间件, 作用: 支持异步 action
|--src
|-- store Redux 目录
- |-- actions.JS
- |-- index.JS
- |-- reducers.JS
- |-- state.JS
|-- components 组件目录
|-- Test.jsx
|-- App.JS 项目入口
准备工作
第 1 步: 提供默认值, 既然用 Redux 来管理数据, 那么数据就一定要有默认值, 所以我们将 state 的默认值统一放置在 state.JS 文件:
- // state.JS
- // 声明默认值
- // 这里我们列举两个示例
- // 同步数据: pageTitle
- // 异步数据: infoList(将来用异步接口获取)
- export default {
- pageTitle: '首页',
- infoList: []
- }
第 2 步: 创建 reducer, 它就是将来真正要用到的数据, 我们将其统一放置在 reducers.JS 文件
- // reducers.JS
- // 工具函数, 用于组织多个 reducer, 并返回 reducer 集合
- import { combineReducers } from 'redux'
- // 默认值
- import defaultState from './state.js'
- // 一个 reducer 就是一个函数
- function pageTitle (state = defaultState.pageTitle, action) {
- // 不同的 action 有不同的处理逻辑
- switch (action.type) {
- case 'SET_PAGE_TITLE':
- return action.data
- default:
- return state
- }
- }
- function infoList (state = defaultState.infoList, action) {
- switch (action.type) {
- case 'SET_INFO_LIST':
- return action.data
- default:
- return state
- }
- }
- // 导出所有 reducer
- export default combineReducers({
- pageTitle,
- infoList// 欢迎加入全栈开发交流圈一起学习交流: 864305860
- })// 面向 1-3 年前端人员
- // 帮助突破技术瓶颈, 提升思维能力
第 3 步: 创建 action, 现在我们已经创建了 reducer, 但是还没有对应的 action 来操作它们, 所以接下来就来编写 action
- // actions.JS
- // action 也是函数
- export function setPageTitle (data) {
- return (dispatch, getState) => {
- dispatch({ type: 'SET_PAGE_TITLE', data: data })
- }
- }
- export function setInfoList (data) {
- return (dispatch, getState) => {
- // 使用 fetch 实现异步请求
- Windows.fetch('/api/getInfoList', {
- method: 'GET',
- headers: {
- 'Content-Type': 'application/json'
- }
- }).then(res => {
- return res.JSON()
- }).then(data => {
- let { code, data } = data
- if (code === 0) {
- dispatch({ type: 'SET_INFO_LIST', data: data })
- }
- })
- }
- }
最后一步: 创建 store 实例
- // index.JS
- // applyMiddleware: redux 通过该函数来使用中间件
- // createStore: 用于创建 store 实例
- import { applyMiddleware, createStore } from 'redux'
- // 中间件, 作用: 如果不使用该中间件, 当我们 dispatch 一个 action 时, 需要给 dispatch 函数传入 action 对象; 但如果我们使用了这个中间件, 那么就可以传入一个函数, 这个函数接收两个参数: dispatch 和 getState. 这个 dispatch 可以在将来的异步请求完成后使用, 对于异步 action 很有用
- import thunk from 'redux-thunk'
- // 引入 reducer
- import reducers from './reducers.js'
- // 创建 store 实例
- let store = createStore(
- reducers,
- applyMiddleware(thunk)
- )
- export default store
至此, 我们已经完成了所有使用 Redux 的准备工作, 接下来就在 React 组件中使用 Redux
开始使用
首先, 我们来编写应用的入口文件 App.JS
- // App.JS
- import React from 'react'
- import ReactDOM from 'react-dom'
- // 引入组件
- import TestComponent from './components/Test.jsx'
- // Provider 是 react-redux 两个核心工具之一, 作用: 将 store 传递到每个项目中的组件中
- // 第二个工具是 connect, 稍后会作介绍
- import { Provider } from 'react-redux'
- // 引入创建好的 store 实例
- import store from '@/store/index.js'
- // 渲染 DOM
- ReactDOM.render (
- (
- <div>
- {/* 将 store 作为 prop 传入, 即可使应用中的所有组件使用 store */}
- <Provider store = {store}>
- <TestComponent />
- </Provider>
- </div>
- ),
- document.getElementById('root')
- )
最后是我们的组件: Test.jsx
- // Test.jsx
- import React, { Component } from 'react'
- // connect 方法的作用: 将额外的 props 传递给组件, 并返回新的组件, 组件在该过程中不会受到影响
- import { connect } from 'react-redux'
- // 引入 action
- import { setPageTitle, setInfoList } from '../store/actions.js'
- class Test extends Component {
- constructor(props) {
- super(props)
- }
- componentDidMount () {
- let { setPageTitle, setInfoList } = this.props
- // 触发 setPageTitle action
- setPageTitle('新的标题')
- // 触发 setInfoList action
- setInfoList()
- }
- render () {
- // 从 props 中解构 store
- let { pageTitle, infoList } = this.props
- // 使用 store
- return (
- <div>
- <h1>{pageTitle}</h1>
- {
- infoList.length> 0 ? (
- <ul>
- {
- infoList.map((item, index) => {
- <li>{item.data}</li>
- })
- }
- </ul>
- ):null
- }
- </div>
- )
- }
- }
- // mapStateToProps: 将 state 映射到组件的 props 中
- const mapStateToProps = (state) => {
- return {
- pageTitle: state.pageTitle,
- infoList: state.infoList
- }
- }
- // mapDispatchToProps: 将 dispatch 映射到组件的 props 中
- const mapDispatchToProps = (dispatch, ownProps) => {
- return {
- setPageTitle (data) {
- // 如果不懂这里的逻辑可查看前面对 redux-thunk 的介绍
- dispatch(setPageTitle(data))
- // 执行 setPageTitle 会返回一个函数
- // 这正是 redux-thunk 的所用之处: 异步 action
- // 上行代码相当于
- /*dispatch((dispatch, getState) => {
- dispatch({ type: 'SET_PAGE_TITLE', data: data })
- )*/
- },
- setInfoList (data) {
- dispatch(setInfoList(data))
- }
- }
- }
- export default connect(mapStateToProps, mapDispatchToProps)(Test)
Redux 三大原则
单一数据源
整个应用的 state 被储存在一棵 object tree 中, 并且这个 object tree 只存在于唯一一个 store 中
State 是只读的
唯一改变 state 的方法就是触发 action,action 是一个用于描述已发生事件的普通对象
使用纯函数来执行修改
为了描述 action 如何改变 state tree , 你需要编写 reducers
结语
感谢您的观看, 如有不足之处, 欢迎批评指正.
来源: http://www.qdfuns.com/article/51117/f88583787d420d690033acda0fbe2508.html