![](/img/trans.png)
[英]How to keep changes made to a class when the page refreshes with Javascript
[英]Problems saving data passed through Redux when page refreshes or changes
每當此項目選擇添加到購物車時,我正在嘗試保存用戶的項目選擇。 每當用戶按下添加到特定項目的購物車時,我都會使用Redux傳遞商品數據。 在我的Cart
組件中,我可以查看添加到購物車的最后一個項目的項目選擇數據。 此用戶選擇項數據類似於Object {price: 25, item: "Hoodie", size: "medium"}
。 我希望能夠存儲我的Cart
組件中添加到購物車的每個選擇。 這是Cart
:
import React, { Component } from 'react';
import {addCart} from './Shop';
import { connect } from 'react-redux';
export class Cart extends Component {
constructor(props) {
super(props);
this.state = {items: this.props.cart,cart: [],total: 0};
}
itemBucket(item) {
this.state.cart.push(this.state.items);
this.countTotal();
}
countTotal() {
var total = 0;
console.log(this.state.cart);
this.state.cart.forEach(function(item, index){
total = total + item.price;
console.log (total);
})
}
componentDidMount () {
window.scrollTo(0, 0);
this.itemBucket();
}
render() {
return(
<div className= "Webcart" id="Webcart">
<addCart cartItem={this.props.cart} />
</div>
);
}
}
const mapDispatchToProps = (dispatch) => {
return {
onCartAdd: (cart) => {
dispatch(addCart(cart));
},
}
}
function mapStateToProps(state) {
return { cart: state.cart };
}
export default connect(mapStateToProps, mapDispatchToProps)(Cart);
我將itemBucket()
設置為一個函數,將每個項目選擇添加到state
找到的購物車數組中。 但是這不起作用,只傳遞添加到購物車的最后一項。 這可能與改變我的Redux Store的工作方式有關,但我真的不知道如何應用它。 這是我的Redux商店:
import { createStore, applyMiddleware } from 'redux';
import reducer from './reducers';
import thunkMiddleware from 'redux-thunk';
import {createLogger} from 'redux-logger';
const store = createStore(
reducer,
applyMiddleware(
createLogger(),
thunkMiddleware
)
);
export default store;
即使頁面刷新或更改,如何保存傳遞給Cart
每個項目?
編輯
這是我的reducer組件:
import {ADD_CART} from './actions';
export default Reducer;
var initialState = {
cart:{},
data: [],
url: "/api/comments",
pollInterval: 2000
};
function Reducer(state = initialState, action){
switch(action.type){
case ADD_CART:
return {
...state,
cart: action.payload
}
default:
return state
};
}
目前,您的應用中發生的事情是,每次頁面刷新時,redux存儲都會初始化並使用reducer提供的默認值。
您可以通過在createStore
提供一個對象作為第二個參數來覆蓋這些默認值。
const store = createStore(
reducer, // default values provided by reducers
{key: "value"}, // overwrites matching key/val pairs, think Object.assign with the first reducer argument
applyMiddleware(createLogger(), thunkMiddleware)
)
此示例使用瀏覽器的localStorage來存儲和檢索數據。
localStorage.js
文件使用redux狀態作為要存儲在localStorage中的數據。
localStorage.js
export const loadState = () => {
try {
let serializedState = localStorage.getItem('state')
if (serializedState === null) {
return undefined
}
let storageState = JSON.parse(serializedState)
return storageState
} catch (err) {
return undefined
}
}
export const saveState = (state) => {
try {
const serializedState = JSON.stringify(state)
// saves state to localStorage
localStorage.setItem('state', serializedState)
} catch (err) {
console.log('error and unable to save state', err)
}
}
現在,您可以配置redux存儲,以便在初始化時,檢索localStorage中的“state”項,並覆蓋默認的reducer值。
saveState
函數將保持redux狀態。 它通過使用store.subscribe()
監聽redux商店中的更改來實現此store.subscribe()
。 發生更改時,將調用saveState
。
安裝lodash以啟用限制,否則saveState將被調用太多次。
configureStore.js
import { createStore, applyMiddleware } from 'redux'
import reducer from './reducers';
import thunkMiddleware from 'redux-thunk'
import createLogger from 'redux-logger'
import { loadState, saveState } from './localStorage'
import throttle from 'lodash/throttle'
let middlewares = [createLogger(), thunkMiddleware]
const configureStore = () => {
const localStorageState = loadState()
const store = createStore(
reducer,
localStorageState,
applyMiddleware(...middlewares)
)
// everytime the state changes, it will be saved to
store.subscribe(throttle(() => {
saveState(store.getState())
}, 1000))
return store
}
export default configureStore
現在按以下方式創建商店。
index.js
import configureStore from './configureStore'
const store = configureStore()
此實現演示了如何直接與localStorage交互,並從Dan那里獲取了這個想法。 您可以稍后優化此存儲和檢索過程。 目前,只要在商店中發生更改,整個redux狀態就會寫入localStorage。
一旦您更接近為redux商店建立數據結構,您可以慢慢分解狀態樹並將它們設置為localStorage中的單個項目。 (一種可能的解決方案
然后,您訂閱/偵聽特定的狀態樹而不是整個存儲,並在發生更改時保存它們。
store.getState().some.data.set
而不是store.getState()
另外,請查看npm,有些人已經創建了一些很好的方法來解決這個問題。
我的建議是使用redux-persist
將購物車狀態保存到localStorage。 與編寫自己的實現相比,它會更容易,並且擁有一個活躍的社區(因此,如果您遇到任何問題/錯誤,您可能不會是唯一的問題/錯誤)。
Redux商店
import { createStore, applyMiddleware, compose } from 'redux';
import { persistStore, autoRehydrate } from 'redux-persist';
import reducer from './reducers';
import thunkMiddleware from 'redux-thunk';
import { createLogger } from 'redux-logger';
const store = createStore(
reducer,
undefined,
compose(
applyMiddleware(createLogger(), thunkMiddleware),
autoRehydrate()
)
);
persistStore(store, { whitelist: ['cart'] });
export default store;
減速器
import { ADD_CART } from './actions';
import { REHYDRATE } from 'redux-persist/constants';
export default Reducer;
var initialState = {
cart:{},
data: [],
url: "/api/comments",
pollInterval: 2000
};
function Reducer(state = initialState, action){
switch(action.type){
case REHYDRATE:
if (action.payload && action.payload.cart) {
return { ...state, ...action.payload.cart };
}
return state;
case ADD_CART:
return {
...state,
cart: action.payload
}
default:
return state
};
}
請參閱此處的完整文檔: https : //github.com/rt2zz/redux-persist
我將itemBucket()設置為一個函數,將每個項目選擇添加到狀態中找到的購物車數組中。 但是這不起作用,只傳遞添加到購物車的最后一項。
使用
constructor(props) {
super(props);
this.state = {cart: this.props.cart,total: 0};
}
itemBucket(item) {
this.setState({cart : [...this.state.cart, item]});
}
componentDidUpdate(){
this.countTotal();
}
countTotal將顯示舊購物車,如果放入itemBucket,因為setState不同步。 你可以把它放在componentDidUpdate中。
對於刷新之間,可以使用服務調用在服務器上存儲購物車以發布計數,或使用localStorage / sessionStorage / indexedDb將其保留在客戶端中。 在componentWillMount中,從上面的位置獲取此信息,並在客戶端上使用它來補充您的redux商店。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.