您现在的位置是:首页 >学无止境 >React之购物车+动态获取参数+Hooks+Redux网站首页学无止境
React之购物车+动态获取参数+Hooks+Redux
1、redux-logger中间件
1️⃣:安装redux-logger依赖包
yarn add redux-logger
2️⃣:在store的配置文件index中配置
import {legacy_createStore as applyMiddleware,applyMiddleware} from 'redux'
import counterReducer from './counterReducer'
import {composeWithDevTools} from 'redux-devtools-extension'
import logger from 'redux-logger'
const store=createStore(counterReducer,composeWithDevTools(applyMiddleware(logger)))
export default store
购物车
1️⃣:在actionType.js文件中编写代码
export const GETSHOPCARLIST = 'getShopCarList'
2️⃣:在action文件下创建shopAction.js,action是一个对象,里面有个type属性,,主要是组件通过type来通知action需要更新数据。
import * as actionTypes from './actionTypes'
export const getShopCarList = (payload)=>({type:actionTypes.GETSHOPCARLIST,payload})
⚠️:payload为组件传的值
3️⃣:编写reducer,reduce响应action通知对象,经过处理,将通过return 将state发送给store
import * as actionTypes from '../action/actionTypes'
const shopCarReducer = (state={
shopcarList:[]
},action)=>{
switch(action.type){
case actionTypes.GETSHOPCARLIST:
return {...state,shopcarList:action.payload}
default:
return state
}
}
export default shopCarReducer
⚠️:...state解构,将action中的值赋给shopcarList
4️⃣:在组件中分别入Hooks组件:useSelector``useDispatch
useDispatch:调用useDispatch(),可以直接获取到dispatch方法,用来发送action
useSelector:参数为回调函数,在回调函数中可以获取到仓库的状态,然后通过return出数据,用一个变量来接,然后正常使用
import React ,{useEffect,useMemo,useRef}from 'react'
import {useDispatch, useSelector} from 'react-redux'
export default function ShopCar(){
const dispatch = useDispatch()
const list = useSelector((state)=>{
return state.shopCart.shopcarList
})
return (
<div>
<Table columns={column} dataSource={list} rowKey={'_id'} bordered={true} pagination={false}></Table>
<div>总价:{totalPrice}</div>
</div>
)
}
⚠️:通过useEffect,调用dispatch(getShopCarListAsync)获取购物车列表内容
5️⃣编写thunk的异步方法
-
安装redux-thunk依赖
yarn add reduc-thunk
-
导入thunk
import thunk from 'redux-thunk'
-
使用thunk
const store=createStore(bigReducer,composeWithDevTools(applyMiddleware(thunk)))
redux的作用:让dispatch方法能够接收函数作为参数
6️⃣:编写redux-logger
import logger from 'redux-logger'
const store=createStore(counterReducer,composeWithDevTools(applyMiddleware(logger)))
redux-logger是为了打印日志,记录日志
7️⃣:在store入口文件引入shopReducer,并且将shopReducer放入createStore函数中.
import {legacy_createStore as createStore,applyMiddleware,combineReducers} from 'redux'
import shopCarReducer from './shopReduce/shopReduce'
const bigReducer = combineReducers({
shopCart:shopCarReducer
})
const store=createStore(bigReducer,composeWithDevTools(applyMiddleware(logger,thunk)))
export default store
8️⃣:将store注册到全局,使用Redux的Provider,
import { Provider } from 'react-redux'
root.render(
<Provider store={store}>
<App></App>
</Provider>
)
Redux的Provider是React-Redux库提供的一个组件,它可以将Redux store传递给整个React应用程序。在使用React-Redux时,我们需要在应用程序的最顶层使用Provider组件,以便所有的子组件都能访问到Redux store中的状态数据。
9️⃣编写shopAsync异步文件
-
导入axios
import axios from "axios"
-
导入shopAction文件
import {getShopCarList} from '../action/shopAction'
-
编写thunk的异步方法
export const getShopCarListAsync = async(dispatch,getState)=>{
const {data:{data}} = await axios.get('http://www.zhaijizhe.cn:3001/shopcart/getShopcartData')
dispatch(getShopCarList(data))
}
reudx-thunk的异步方法是异步回调函数
该回调函数参数说明如下
第1个参数:dispatch对象(是redux原生的dispatch对象)
第2个参数:getState():获取store仓库中的state的方法
⚠️: dispatch(getShopCarList(data))
将获取到的列表数据传给action,action接收到值后通过shopReducer将值保存到仓库中
🔟:改变数量的方法
-
在shopAsync异步文件中编写改变数量的异步方法
export const changeCheckedAsync = (arg)=>{
return async(dispatch,getState)=>{
console.log('arg',arg);
const result = await axios.get(`http://www.zhaijizhe.cn:3001/shopcart/checkProducts?_id=${arg}`)
console.log(result.data.code);
if(result.data.code==1){
console.log(123);
dispatch(getShopCarListAsync)
}
}
}
组件dipatch发送action需要传值后,因为reudx-thunk接受值为dispatch,getState,但是调用接口需要传参,这时就需要将changeCheckedAsync改造为回调函数,这样子就能接受到组件传来的值,然后将异步请求函数return出去
11
:编写勾选的异步代码:
export const changeCheckedAsync = (arg)=>{
return async(dispatch,getState)=>{
console.log('arg',arg);
const result = await axios.get(`http://www.zhaijizhe.cn:3001/shopcart/checkProducts?_id=${arg}`)
console.log(result.data.code);
if(result.data.code==1){
console.log(123);
dispatch(getShopCarListAsync)
}
}
}
12
:组件代码遇到的问题
-
在使用antd-design中的Input组件,需要获取Input的值,通过useRef来获取值
{
title:'输入购买量',
width:'150px',
render:(text)=>{
return <Input style={{width:'150px'}} defaultValue={text.num} ref={inputnum} onBlur={()=>{NumInput(text._id)}}></Input>
}
},
这里需要注意的是用的是onBlur事件
-
Table组件中获取该行的值,通过text参数,参数text拿到的是该行的对象
title:'小计',
align:'center',
render:(text)=>{
let data = text.price*text.num
return data.toFixed(2)
}