Redux基本使用

redux中基础概念

  • store:是一个存储state的对象,可以跟踪数据的变化。
  • action:redux要求通过action来更新数据。所有数据的变化必须通过dispatch action 来更新数据;另外action是一个普通的js对象,用来描述更新的type和内容。
  • reducer:reducer是一个纯函数,它将传入的state和action结合起来生成一个新的state。

基本使用

const { createStore } = require('redux')

// 初始的数据  这个数据只会使用一次
const initstate = {
  name: 'Cooper',
  counter:0
}

// 定义reducer
// 每次返回应该是上一个state
function reducer(state =initstate ,action) {
  return state
}

// 创建store
const store = createStore(reducer)

// 数据的获取
console.log(store.getState());

状态的修改

const { createStore } = require('redux')

// 初始的数据  这个数据只会使用一次
const initstate = {
  name: 'Cooper',
  counter: 0
}

// 定义reducer
// 每次返回应该是上一个state
function reducer(state = initstate, action) {
  switch (action.type) {
    case 'change_name':
      return { ...state, name: action.name }  // 这里要返回一个新的对象,否则的话页面将不会更新数据
    default:
      return state
  }
}

// 创建store
const store = createStore(reducer)


// 数据的获取
console.log(store.getState());  // {name: 'Cooper',counter:0}

const nameAction = { type: 'change_name', name: '张三' }
store.dispatch(nameAction)  //每次dispatch内部会再一次执行reducer函数

console.log(store.getState());  // {name: '张三',counter:0}

订阅state的变化

const { createStore } = require('redux')

// 初始的数据  这个数据只会使用一次
const initstate = {
  name: 'Cooper',
  counter: 0
}

// 定义reducer
// 每次返回应该是上一个state
function reducer(state = initstate, action) {
  switch (action.type) {
    case 'change_name':
      return { ...state, name: action.name }  // 这里要返回一个新的对象,否则的话页面将不会更新数据
    default:
      return state
  }
}
// 创建store
const store = createStore(reducer)
// 数据的获取
const nameAction = { type: 'change_name', name: '张三' }
const nameAction2 = { type: 'change_name', name: '李四' }

const unsubscribe = store.subscribe(() => {
  console.log('state变化了');   // 每次dispatch state变化时执行该函数
})

store.dispatch(nameAction)  //每次dispatch内部会再一次执行reducer函数

unsubscribe()  // 取消订阅

store.dispatch(nameAction2)  //每次dispatch内部会再一次执行reducer函数

动态生成action

封装成一个函数,在项目时可以定义一个actionCreator文件夹

const { createStore } = require('redux')

// 初始的数据  这个数据只会使用一次
const initstate = {
    name: 'Cooper',
    counter: 0
}

// 定义reducer
// 每次返回应该是上一个state
function reducer(state = initstate, action) {
    switch (action.type) {
        case 'change_name':
            return { ...state, name: action.name }  // 这里要返回一个新的对象,否则的话页面将不会更新数据
        default:
            return state
    }
}
// 创建store
const store = createStore(reducer)
// 数据的获取
// const nameAction = { type: 'change_name', name: '张三' }
// const nameAction2 = { type: 'change_name', name: '李四' }

function actionCreator(name) {
    return {
        type: 'change_name',
        name
    }
}

const unsubscribe = store.subscribe(() => {
    console.log('state变化了');   // 每次dispatch state变化时执行该函数
})

store.dispatch(actionCreator('张三'))  //每次dispatch内部会再一次执行reducer函数

unsubscribe()  // 取消订阅

store.dispatch(actionCreator('李四'))  //每次dispatch内部会再一次执行reducer函数

redux 文件夹划分

  • src/
    • store/
      • actionCreator.js
      • constant.js
      • index.js
      • reducer.js

redux 原则

Snipaste_2023-04-09_15-07-04.png

react中使用redux

import React from 'react'
import store from '../store/index'
import { useEffect, useState } from "react";
import {decreaNumAction } from '../store/actionCreator'
export default function Home() {
  const [count, setCount] = useState(store.getState().count)
  useEffect(() => {
    store.subscribe(() => {
      setCount(store.getState().count)
    })
  }, [count])
  return (
    <div>
      <p>Home count:{ count }</p>
      <button onClick={()=>store.dispatch(decreaNumAction(5))}>-5</button>
    </div>
  )
}

**react-redux的使用 **

  1. 给整个应用程序提供store
import React from 'react';
import ReactDOM from 'react-dom/client';
import App from './App';
import { Provider} from 'react-redux'
import store from './store';
const root = ReactDOM.createRoot(document.getElementById('root'));
root.render(
  <React.StrictMode>
    <Provider store={store}>
      <App />
    </Provider>
  </React.StrictMode>
);
  1. 将store连接到组件上,并且将store中数据映射到组件中
import React, { useState } from 'react'
import { connect } from 'react-redux'

function About({ count}) {
  return (
    <div>
      <p>About count:{count}</p>
      <button>+10</button>
    </div>
  )
}

const mapStateToProps = (state) => {
  return {
    count:state.count
  }
}

export default connect(mapStateToProps)(About)
  1. 状态的修改
import React from 'react'
import { connect } from 'react-redux'
import{addNumAction } from '../store/actionCreator'
function About({ count,addnumber }) {
  const handleAdd = () => {
    addnumber(10)
  }
  return (
    <div>
      <p>About count:{count}</p>
      <button onClick={handleAdd}>+10</button>
    </div>
  )
}

const mapStateToProps = (state) => {
  return {
    count:state.count
  }
}

const mapDispatchProps = (dispatch) => {
  return {
    addnumber(num) {
      dispatch(addNumAction(num))
    }
  }
}

export default connect(mapStateToProps,mapDispatchProps)(About)

redux使用redux-thunk中间件实现异步操作

  1. 使用中间件
import { createStore,applyMiddleware } from 'redux'
import thunk from 'redux-thunk'
import reducer from './reducer'

const store = createStore(reducer,applyMiddleware(thunk))

export default store
  1. 异步操作
export const changeBannersAction = (banners) => ({
  type:actionTyoe.CHANGEBANNERSACTION,
  banners
})
export const getBanners = () => {
  return function (dispatch, getState) {
    axios.get('http://123.207.32.32:8080/home/multidata').then(res => {
      const banners = res.data.data.banner.list
      dispatch(changeBannersAction(banners))
    })
  }
}
  1. 组件中使用派发
import React, { useEffect } from 'react'
import { connect } from 'react-redux'
import { getBanners } from '../store/actionCreator'
function About({ count, addnumber, banners,getBanners }) {

  useEffect(() => {
    getBanners()
  })
  return (
    <div>
      <h6>banners数据</h6>
      <ul className='bannner'>
        {banners.map((item, idx) => {
      return <li key={idx}>{item.title}</li>
    })}
      </ul>
    </div>
  )
}

const mapStateToProps = (state) => {
  return {
    banners: state.banners
  }
}

const mapDispatchProps = (dispatch) => {
  return {
    getBanners() {
      dispatch(getBanners())
    }

  }
}

export default connect(mapStateToProps, mapDispatchProps)(About)

注意dispatch只能派发一个对象,如果想要派发一个函数,只能利用react-thunk中间件来实现

集成redux devTool

import { createStore,applyMiddleware, compose } from 'redux'
import thunk from 'redux-thunk'
import reducer from './reducer'

const composeEnhancers = window.__REDUX_DEVTOOLS_EXTENSION_COMPOSE__||compose  // 集成redux-devtool
const store = createStore(reducer,composeEnhancers(applyMiddleware(thunk)))

export default store

Reducers 拆分

reducers拆分.png

combineReduces将两个reducers返回的对象合并成一个对象使用mapStateToProps 拿状态值的时候要xxx.counterInfo.xxx

Redux Toolkit和Redux-Redux结合使用

// 第一步 创建store
import { configureStore } from '@reduxjs/toolkit';
import counterReducer from './counterSlice';

export default configureStore({
  reducer: {
    count: counterReducer,
  },
});

// 第二步 创建切片
import { createSlice } from '@reduxjs/toolkit';
export const counterSlice = createSlice({
  name: 'counter',
  initialState: {
    value: 0,
  },
  reducers: {
    increment: state => {
      state.value++
    },
  },
});

// 每个reducers  都将会生成一个Action creators
export const { increment } = counterSlice.actions;
export default counterSlice.reducer;

// 第三步 为全局注入store
import store from './redux/store';
import { Provider} from 'react-redux'

<Provider store={store}>
  <HashRouter>
    <App />
  </HashRouter>
</Provider>

// 第四步 在组件中使用  获取state和派发事件
import { useSelector, useDispatch } from 'react-redux';
import { increment } from '../redux/counterSlice';
const value = useSelector(state=>state.count.value)
const dispatch = useDispatch()

const handleClick = ()=>{
  dispatch(increment())
}
  • 11
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值