redux的使用

redux

集中式状态管理工具

起源

 

2014年 Facebook 提出了 Flux 架构的概念,采用 单向数据流 思想。

 

2015年,Redux 出现,`,很短时间内就成为了最热门的状态管理架构。

Redux 概述

  • yarn add redux

Redux 是 JavaScript 应用的可预测状态容器,用来集中管理状态。 特点:集中管理、可预测、易于测试、易于调试、强大的中间件机制满足你所有需求。 注意:redux 是一个独立于 react 的库,可以配合任何 UI 库/框架来使用。

redux的三大原则

  1. 单一数据源

  2. State是只读的

  3. 使用纯函数来执行修改

什么情况下需要使用redux

  1. 总体原则: 大型项目状态管理复杂才用

  2. 某个组件的状态,需要共享

  3. 某个状态需要在任何地方都可以拿到

  4. 一个组件需要改变全局状态

  5. 一个组件需要改变另一个组件的状态

三个核心概念

计数器案例:点击 +1 按钮,数值加1(React 关注 UI,Redux 关注 state)。 计数器案例的 state: { count: 0 } 。

  • Action(“砖”家):描述要执行的行为动作,比如要让计数器的值加1(提出想法)。

  • Reducer(劳动者):接收 Action 完成该动作,比如完成值加1得到新状态 { count: 1 }(实现想法)。

  • Store(管理者):是 Action 和 Reducer 的桥梁,将 Action 传递给 Reducer。

action

  • action 是一个原生 JavaScript 对象。

  • 作用:描述要执行的行为动作,提供完成该动作需要的数据。比如:计数器案例 +1 就是一个动作

  • 约定1:必须提供 type 属性,用于描述动作类型。

  • 约定2:type 属性的值是字符串,约定使用全大写字母。

  • 约定3:可以提供其他属性,提供完成该动作需要的数据。

  • 简化操作:使用函数来创建 action,将该函数叫做 action creator。

{ type: 'INCREMENT', }
​
// todo app,添加任务的action:
{ type: 'ADD_TODO', text: '学习Redux' }
// action creator:
const increment = () => ({ type: 'INCREMENT' })
// 创建action
increment()

reducer

  • reducer 是一个函数。

  • 作用:接收 action 和 state(初始 state), 完成该行为动作,并返回新 state。

  • 代码解释:(state, action) => newState。

  • 约定:不要直接修改 state,而是,根据当前 state 得到新的 state。

  • 注意:reducer 应该是一个纯函数(同样的输入,必定得到同样的输出),不要有修改参数、调用 Math.random() 等不纯的操作。

const counter = (state, action) => {
  switch (action.type) {
    case 'INCREMENT':
      return state + 1 // state++ 表示直接修改当前 state
    default:           // 必须得有!默认返回当前 state
      return state
  }
}

store

  • Redux 的 state 仓库。一个 redux 应用只有一个 store。

  • 作用:将 action 和 reducer 组合到一起。

  • 职责:

    • 1 提供整个应用的 state

    • 2 提供 dispatch 方法,用来触发 action

    • 3 提供 getState 方法,用来获取整个应用的 state

    • 4 提供 subscribe 方法,监听 state 变化。

import { createStore } from 'redux'
import counter from './reducer'
// 接收 reducer 作为参数,创建 store
const store = createStore(counter)
store.getState() // 获取state
store.dispatch({}) // 触发 action
const unsubscribe = store.subscribe(() => {}) // 监听 state 变化
//调用unsubscribe()取消监听state变化

redux的基本使用

// 1.安装
 yarn add redux
// 2.在js文件中从redex包里面导入createStore函数
import { createStore } from 'redux'
//3. 创建store,将reducer传入到store中
const store = createStore(reducer)
// 4. 定义redecer函数 
//  要接收两个参数: state, action
//  注意:在定义reducer的时候,通过es6语法设置默认值的方式,初始化state的值
function reducer(state = 0, action) {
  switch (action.type) {
    case 'INCREMENT':
      return state + 1
    default:
      return state //一定要写一个默认情况,返回原来的state
  }
}
// 调用subscribe,监听state的变化 注意: 要在dispatch之前调用
store.subscribe(() => {
  console.log(store.getState())
})
​
//console.log(store.getState()) //获取store中state的状态值
store.dispatch({ type: 'INCREMENT' }) // 分发action
store.dispatch({ type: 'INCREMENT' }) // 分发action
//console.log(store.getState())
​

redux的内部执行原理

// 创建store的时候,会自动调用一次reducer函数
const store = createStore(reducer)
// redux内部会创建一个action {type: "@@redux/INIT8.v.s.i.j.j"}
// 目的是让reducer中执行默认的返回值,从而拿到state的初始化值
function reducer(state = 0, action) {
  switch (action.type) {
    case 'INCREMENT':
      return  state + 1
    default:
      return state //一定要写一个默认情况,返回原来的state
  }
}
​
​
store.dispatch({ type: 'INCREMENT' }) //这次分发action,reducer中拿到的state 0
store.dispatch({ type: 'INCREMENT' }) // 这次分发action,reducer中拿到的state 1
//console.log(store.getState())

react-redux

  • Redux 只能用来管理应用的 state。

  • 如果要配合 react 使用,需要借助 react-redux 这个绑定库。

核心API

  • Provider 组件:用来包裹整个 React 应用,接收 store 属性,为应用提供 state 和 操作 state 的方法。

  • connect 函数:连接 Redux 和 React 组件,为被包裹的组件提供 state 和 操作 state 的方法。 组件中通过 props 获取 Redux store 的内容。

import { Provider } from 'react-redux'
<Provider store={store}>
  <App />
</Provider>
connect()(Counter)
// mapStateToProps 函数:提供组件用到的state,作为组件的props,传递给 Counter 组件
// mapDispatchToProps 函数:提供组件用到的操作state的方法,作为组件的props ,传递给 Counter 组件
//注意: 这两个参数是函数,一定要有返回值(返回值是对象)并且都是可选的(可以不传) 
connect(mapStateToProps, mapDispatchToProps)(Counter)

使用步骤

  • 1 安装:yarn add react-redux

  • 2 导入 Provider 组件。

  • 3 使用 Provider 组件,作为 React 应用的根组件,包裹整个应用。

  • 4 将 redux 的 store 作为 Provider 组件 store 属性的值。

  • 5 导入 connect 函数(将 React 组件 和 Redux store 链接在一起)。

  • 6 使用 connect 函数,包装 React 组件。

  • 7 在 React 组件中,通过 props 获取到 Redux store 中的state。

//导入provider和connect
import { Provider, connect } from 'react-redux'

// 定义的函数组件
function Counter(props) {
  console.log(props) //默认可以获取到dispatch方法
  return (
    <div>
      <div>{props.count}</div>
      <button onClick={() => props.onincrement()}>+1</button>
    </div>
  )
}
//使用connect包装Counter组件
const WithCounter = connect(
  mapState,
  mapDispatch
)(Counter)

//connect要用的第一个参数 
// state是redux中的state
const mapState = state => {
  return {
      // 这里return的内容就是react组件中props接收到的数据
    count: state
  }
}
//connect要用的第二个参数
//dispatch 是redux中的dispath
const mapDispatch = dispatch => {
  return {
       // 这里return的内容就是react组件中props接收到的数据
    onincrement() {
      dispatch({ type: 'INCREMENT' })
    }
  }
}
//最终使用包装后的组件
ReactDOM.render(
  <Provider store={store}>
    <WithCounter></WithCounter>
  </Provider>,
  document.getElementById('root')
)

react-redux 简写形式

// loading和getUserDataAsync 是连个actionCeater函数
import {
  loading,
  getUserDataAsync
} from './redux/actions'

// 基础写法: 
let mapStateToProps = state => {
  // console.log(state)
  return {
    ...state
  }
}
let mapDisPatchToProps = dispatch => {
  return {
    loading: () => {
      dispatch(loading())
    },
    getUserDataAsync: searchname => {
      dispatch(getUserDataAsync(searchname))
    }
  }
}
connect(
 mapStateToProps,
 mapDisPatchToProps
)(UI组件)
// 简写形式:
// 上面的方式可以简写成下面这种方式:
connect(
  state => ({ ...state }),
  { loading, getUserDataAsync }
)(UI组件)

两种类型的组件

  • 展示组件(UI组件)

    • 可以理解为: 不跟 redux 关联的组件(要传入connect() 中的组件 )

    • 特点: 提供了组件的结构和样式

<Todo />

  • 容器组件

    • 可以理解为: 跟 redux 密切关联的组件( 调用 connect() 之后得到的组件 )

    • 特点: 专门与 redux 进行交互

// 容器组件
// withTodo 就是容器组件
const withTodo = connect()(Todo)

redux-thunk 使用

1. 安装:yarn add redux-thunk
2. 导入thunk    import thunk from 'redux-thunk'
3. 导入redux中的一个函数:`applyMiddleware`
4. 将redux-thunk中间件,作为参数传递给 applyMiddleware
5. 将 middlewares 传递给 createStore,作为它的第三个参数
import thunk from 'redux-thunk'

// 注意: logger 中间件应该放在后面
createStore(reducer,applyMiddleware(thunk,中间件,中间件))
  • 注意:redux-thunk对 action 做了处理,异步操作就是放在action中被处理的!!!

// 同步的action 
const increment = () => {
   return { type: 'INCREMENT' }
}
//异步的action  --要求返回一个函数,这个函数可以拿到dispatch
const incrementAsync = () => {
    //thunk会处理这个函数,将dispatch传入到函数中
  return function(dispatch) {
    setTimeout(() => {
        dispatch({ type: 'INCREMENT' })
    }, 2000)
  } 
}

注意: 标准的异步请求应该有三个状态, 1.等待 2.成功 3.失败

chrome的redux插件

// 1. 单独使用 redux 浏览器插件:
const store = createStore(
  reducer,
  initialState,
  // 单独使用 redux 浏览器插件
  window.__REDUX_DEVTOOLS_EXTENSION__ && window.__REDUX_DEVTOOLS_EXTENSION__()
)

// 2. 和中间件配合使用

yarn add redux-devtools-extension -D

import { composeWithDevTools } from 'redux-devtools-extension'

createStore(reducer, initialState, composeWithDevTools(applyMiddleWare(logger)))

combineReducers

  • redux 中提供的一个 API

  • 作用:

    • 1 用来将多个 reducer 合并为一个 根reducer

    • 2 会影响 redux 中的状态值

  • 有了这个方法之后,将来 redux 中就可以有任意多个 reducer,这样,每个 reducer 只需要处理某个特定的状态即可。

  • 注意:每个 reducer 中的状态最终被全部合并到一个对象中。对象中的键就是参数对象的键

import { createStore, combineReducers} from 'redux'
const rootReducer = combineReducers({
  todos: reducer,
  filter:filter
})

const store = createStore( rootReducer )

store.getState() // 初始状态: { todos: [], filter: 'all' }
// 此时的应用的状态为:{ todos: [], filter: 'all' }
const rootReducer = combineReducers({
  todos: reducer,
  filter
})

// 该写法等价于上述combineReducers调用:
function rootReducer(state = {}, action) {
  return {
    todos: reducer(state.todos, action),
    filter: filter(state.filter, action)
  }
}

// 当我们使用 dispatch( 动作 ) 分发了一个动作的时候, redux 中所有的 reducer 全部都会执行一次
// 因为 redux 无法知道到底是哪个reducer来处理该状态,所以,所有的 reducer 全部都会被重新执行一次
  • 12
    点赞
  • 15
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
最新版的 react-redux 使用方法如下: 首先,确保你的项目已经安装了 react-redux 依赖包。你可以使用以下命令安装它: ``` npm install react-redux ``` 或 ``` yarn add react-redux ``` 接下来,你需要创建一个 Redux store。你可以使用 Redux Toolkit 来简化这个过程。首先,导入 `configureStore` 和 `getDefaultMiddleware` 函数: ``` import { configureStore, getDefaultMiddleware } from '@reduxjs/toolkit'; ``` 然后,创建一个 rootReducer 来合并你的所有 reducer: ``` import { combineReducers } from 'redux'; const rootReducer = combineReducers({ // 这里是你的 reducer }); ``` 接着,使用 `configureStore` 函数创建 Redux store。你可以通过传入一个对象来配置 store,例如指定 reducer、middleware 等等。以下是一个示例: ``` const store = configureStore({ reducer: rootReducer, middleware: getDefaultMiddleware() }); ``` 现在,你可以使用 `<Provider>` 组件来将 Redux store 提供给你的整个应用程序。在你的根组件中,导入 `<Provider>` 组件和你的 Redux store,然后将其包裹在应用的最外层: ``` import { Provider } from 'react-redux'; ReactDOM.render( <Provider store={store}> <App /> </Provider>, document.getElementById('root') ); ``` 通过将 Redux store 提供给整个应用程序,你可以在应用的任何地方使用 `useSelector` 和 `useDispatch` 钩子来访问 Redux store 中的状态和分发 action。例如,在你的组件中,你可以这样使用: ``` import { useSelector, useDispatch } from 'react-redux'; const MyComponent = () => { const counter = useSelector(state => state.counter); const dispatch = useDispatch(); // 使用 counter 和 dispatch }; ``` 这就是最新版的 react-redux使用方法。你可以根据你的具体需求,自定义配置和使用其他相关的 react-redux API。希望对你有帮助!
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值