营销型网站建设技术指标,重庆 手机网站制作,做食品行业网站,做一个网站指定页面的推广React-Redux总结含购物车案例
reduc简介 redux是react全家桶的一员#xff0c;它为react给i共可预测化的状态管理机制。redux是将整个应用状态存储到一个地方#xff0c;成为store,里面存放着一颗树状态(state,tree),组件可以派发dispatch行为action给store,而不是直接通知其…React-Redux总结含购物车案例
reduc简介 redux是react全家桶的一员它为react给i共可预测化的状态管理机制。redux是将整个应用状态存储到一个地方成为store,里面存放着一颗树状态(state,tree),组件可以派发dispatch行为action给store,而不是直接通知其他组件其他组件可以通过订阅store中的状态state来刷新自己的视图。 主要的四个特征
可预测reducer是纯函数所有状态是可预测的。易调试全局只有一个store。灵活性action,修改state。中心化middleware机制源码简介扩展生态丰富。
设计思想 redux是一种状态管理库用于管理React应用中的全局状态核心思想是将应用的状态集中存储在一个全局的Store中使得状态的变化可追溯可控制可预测。 单一的数据源redux倡导使用单一的数据源的方式来管理应用的状态即整个应用的状态存储再一个全局的JavaScript对象中这有助于简单化状态管理的逻辑使得状态的变化是可预测易于调试的。不可变性redux状态是不可变的即状态一旦创建就不可以修改每次状态发生变化时都会生成一个新的状态对象而不是直接修改原有的状态。这有助于避免状态的不一致和难以追溯的bug。
什么情况下使用redux
某个组件的状态需要让其他组件可以随时拿到(共享)。一个组件需要改变另一个组件的状态(通信)。总体原则是能不用就不用如果不用比较吃力考虑使用。
redux工作流程
component -- dispatch(action) -- reducer -- subscribe -- getState -- component1.触发Action应用中的某个事件或用户行为触发一个ActionAction是一个包含type属性和可选的payload属性通过JavaScript对象用于描述状态的变化。2.派发Action通过调用Redux的dispatch(action)方法将Action派发到Redux的Store中。3.处理ReducerStore接收到Action后会调用所有注册的Reducer函数将当前的状态和Action传入Reducer中。4.更新状态Reducer根据Action的类型处理状态的变化逻辑并返回一个新的状态Redux会将新的状态替代原有的状态从而更新整个应用的状态。5.通知订阅者状态更新后Redux会通过subScribe(listener)方法注册的监听器让他们执行相应的回调函数从而实现对状态变化的监听和响应。
redux的三个核心概念
action 对象描述要做的事情项目中的每一个都是一个action 语法{type:命令,payload:载荷}特点
i.只描述做什么。ii.js对象必须带有type属性用于区分动作的类型。iii.根据功能的不同可以携带额外的数据配合该数据来完成相应的功能。
reducer 函数用来处理action并更新状态是Redux状态更新的地方 语法函数签名:(prevState,action)newState
const reducer (state, action) {switch(action.type){case ADD:state[sum] action.datareturn [...state]break...}
}特点
i.注意该函数一定会有返回值即使状态没有改变也要返回上一次的状态。ii.约定reducer是一个纯函数并不能包含side effect副作用例如不能修改函数参数不能修改函数外部数据不能进行异步操作等。iii.对于reducer来说为了保证reducer是一个纯函数不要直接修改参数state的值也就是不要直接修改当前状态而是根据当前状态值创建新的状态值不要使用Math.random()/new Date()/Date.new()/ajax请求等不纯的操作不要让reducer执行副作用sideEffect
store 仓库,redux的核心整合action和reducer import {createStore} from reduxlet store createStore(reducer)特点
i.一个应用只有一个storeii.维护应用的状态获取状态store.getState()iii.发起状态更新时store.dispatch(action) iv.创建store时接收reducer作为参数const store create Store(reducer)
其他API
i.订阅监听状态变化const unSubscribe store.subscribe((){})ii.取消订阅状态变化unSubscribe()
react-redux概述
概念 在react-redux中有两个核心概念即Provider和connect。provider是一个React组件用于将Redux的Store传递给React应用中的所有组件从而是的组件可以访问到全局的状态。connect是一个高阶函数用于将React组件连接到Redux的store从而实现组件与Redux store之间的数据传递和状态管理。 如何将React组件连接到Redux store 使用connect函数可以将React组件连接到Redux的store。通过在组件定义时调用connect函数并传入需要的参数和回调函数可以将组件与Redux的store进行连接连接后组件可以通过prop访问到Redux Store中的状态并且可以向Redux store派发action 来修改全局状态。 如何使用React-redux的高阶组件和hooks来简化代码 react-redux提供了一些高阶组件和hooks可以帮助简化组件与Redux store之间的交互代码例如mapStateToProps和mapDispatchToProps参数可以帮助组件定义如何从redux store中获取状态和派发action的方式从而减少了在组件中处理Redux store的繁琐代码此外React-redux还提供了一些hooks,例如useSelector和useDispatch可以在函数组件中更方便的访问Redux store的状态和派发action。 react-redux购物车案例 效果
目录结构 action/index.js代码
import { ADD_PRODUCT, REMOVE_PRODUCT } from ../constants;export const addProduct id ({type: ADD_PRODUCT,payload: id
});export const removeProduct id ({type: REMOVE_PRODUCT,payload: id
});cart/cartInte.js代码
import React from react;
import PropTypes from prop-types;const CartItem ({ name, price, quantity, itemTotal, removeProduct }) (div classNamecartWrapperdiv{name}/divdiv${price}/divdivx{quantity}/divdiv ${itemTotal}/divdivbutton onClick{() removeProduct(name)}Remove/button/div/div
);CartItem.propTypes {name: PropTypes.string.isRequired,price: PropTypes.string.isRequired,quantity: PropTypes.number.isRequired,itemTotal: PropTypes.string.isRequired,removeProduct: PropTypes.func.isRequired
};
export default CartItem;cart/index.js代码
import React from react;
import PropTypes from prop-types;
import { connect } from react-redux;
import ./Cart.css;
import CartItem from ./CartItem;
import { getCart, getCartTotal } from ../../reducers;
import { removeProduct } from ../../actions;const Cart ({ cart, cartTotal, removeProduct }) (React.Fragmenth2Checkout Cart/h2{cart.map(({ name, price, quantity, itemTotal }) (CartItemkey{name}name{name}price{price}quantity{quantity}itemTotal{itemTotal}removeProduct{removeProduct}/))}h2Total/h2div classNametotal${cartTotal}/div/React.Fragment
);Cart.propTypes {cart: PropTypes.arrayOf(PropTypes.shape({name: PropTypes.string,price: PropTypes.string,quantity: PropTypes.number,itemTotal: PropTypes.string})),cartTotal: PropTypes.string,removeProduct: PropTypes.func.isRequired
};const mapStateToProps state ({cart: getCart(state),cartTotal: getCartTotal(state)
});
export default connect(mapStateToProps, { removeProduct })(Cart);cart/Cart.css代码
.cartWrapper {display: grid;grid-template-columns: 150px 150px 100px 100px 200px;grid-gap: 10px;white-space: nowrap;
}.total {text-decoration: underline;
}ProductList/index.js代码
import React from react;
import PropTypes from prop-types;
import { connect } from react-redux;
import ./ProductList.css;
import Product from ./Product;
import { getProducts } from ../../reducers;
import { addProduct } from ../../actions;const ProductList ({ products, addProduct }) (React.Fragmenth2Product List/h2{products.map(({ name, price }) (Product key{name} name{name} price{price} addProduct{addProduct} /))}/React.Fragment
);
// propTypes验证在给react组件传属性的的时候定义属性的类型
ProductList.propTypes {products: PropTypes.arrayOf(PropTypes.shape({name: PropTypes.string.isRequired,price: PropTypes.string.isRequired})),addProduct: PropTypes.func.isRequired
};const mapStateToProps state {return { products: getProducts(state) };
};export default connect(mapStateToProps, { addProduct })(ProductList); ProductList/product.js代码
import React from react;
import PropTypes from prop-types;const Product ({ name, price, addProduct }) (div classNameproductWrapperdiv{name}/divdiv{price}/divdivbutton onClick{() addProduct(name)}Add/button/div/div
);Product.propTypes {name: PropTypes.string.isRequired,price: PropTypes.string.isRequired,addProduct: PropTypes.func.isRequired
};export default Product;ProductList/product.css代码
.productWrapper {display: grid;grid-template-columns: 150px 150px 300px;grid-gap: 10px;
}reducers/cart.js代码
import { combineReducers } from redux;
import { ADD_PRODUCT, REMOVE_PRODUCT } from ../constants;//state [id1, id2]
const initialCartAllIds [];
// Reducer状态处理函数
const cartAllIds (state initialCartAllIds, action) {switch (action.type) {case ADD_PRODUCT: {const newItem action.payload;if (state.includes(newItem)) return state;return [...state, action.payload];}case REMOVE_PRODUCT: {const unwantedItem action.payload;return state.filter(item item ! unwantedItem);}default:return state;}
};// state{id: {quantity: productQuantity}}
const initialCartById {};
const cartById (state initialCartById, action) {switch (action.type) {case ADD_PRODUCT: {const newItem action.payload;const newQuantity state[newItem] ? state[newItem].quantity 1 : 1;return { ...state, [newItem]: { quantity: newQuantity } };}case REMOVE_PRODUCT: {const unwantedItem action.payload;const newState { ...state };delete newState[unwantedItem];return newState;}default:return state;}
};export const cart combineReducers({cartAllIds,cartById
});export const getCart (products, cart) {return cart.cartAllIds.map(productName {const name productName;const price products.productById[productName].price;const quantity cart.cartById[productName].quantity;const itemTotal (price * quantity).toFixed(2);return { name, price, quantity, itemTotal };});
};export const getCartTotal (products, cart) {return cart.cartAllIds.reduce((pre, cur) {const price products.productById[cur].price;const quantity cart.cartById[cur].quantity;return pre price * quantity;}, 0).toFixed(2);
};reducers/Products.js代码
import { combineReducers } from redux;
import productsData from ../data;// product ID is the product name in this case
// state {[id]:{name: productName, price: productPrice}}
const initialProductById (function() {const state {};productsData.forEach(({ name, price }) (state[name] { name, price: price.toFixed(2) }));return state;
})();
const productById (state initialProductById, action) {switch (action.type) {default:return state;}
};// state [id1, id2]
const initialProductAllIds productsData.map(product product.name);
const productAllIds (state initialProductAllIds, action) {switch (action.type) {default:return state;}
};export const products combineReducers({productById,productAllIds
});export const getProducts products {return products.productAllIds.map(key products.productById[key]);
};reducers/index.js代码
import { combineReducers } from redux;
import * as productReducer from ./products;
import * as cartReducer from ./cart;const reducer combineReducers({products: productReducer.products,cart: cartReducer.cart
});export const getProducts state productReducer.getProducts(state.products);export const getCart state cartReducer.getCart(state.products, state.cart);export const getCartTotal state cartReducer.getCartTotal(state.products, state.cart);export default reducer;configureStore.js代码
import { createStore } from redux;
import reducer from ./reducers;
import { loadState, saveState } from ./localStorage;const persistedState loadState();const store createStore(reducer,persistedState,window.__REDUX_DEVTOOLS_EXTENSION__ window.__REDUX_DEVTOOLS_EXTENSION__()
);store.subscribe(() {const cartValue store.getState().cart;saveState({ cart: cartValue });
});export default store;constants.js代码
export const ADD_PRODUCT ADD_PRODUCT;
export const REMOVE_PRODUCT REMOVE_PRODUCT;数据源data.js代码
const products [{name: Sledgehammer,price: 125.75},{name: Axe,price: 190.5},{name: Bandsaw,price: 562.13},{name: Chisel,price: 12.9},{name: Hacksaw,price: 18.45}
];export default products;index.js中引入store
import React from react;
import ReactDOM from react-dom;
import { Provider } from react-redux;
import App from ./components/App;
import store from ./configureStore;ReactDOM.render(Provider store{store}App //Provider,document.getElementById(root)
);localStorage.js代码
export const loadState () {try {const valueJSON localStorage.getItem(state);return JSON.parse(valueJSON) || undefined;} catch (error) {return undefined;}
};
export const saveState value {const valueJSON JSON.stringify(value);localStorage.setItem(state, valueJSON);
};效果 新增删除 完结~