在上一篇文章中說過了react中界面A跳到B,返回A,A界面狀態保持不變,上篇中使用的是傳統的localStorage方法,現在來使用第二種redux的state方法來實現這個功能
現在我剛接觸redux,所以可能一些高級方法不是很會用,這邊使用的是很簡單的方法。其實這兩種方法原理差不多,都是通過進行保存原有數據或者重新加載數據來實現
我這邊以購物車的商品為簡單的例子,大家可以根據自己的場景來增加,原理都是一樣的
首先在action.js中定義個保存你數據的方法
// actions.js // 商品相關 export const ADD_To_CART = 'ADD_TO_CART'; export const DELETE_TO_CART ='DELETE_TO_CART'; export const UPDATE_TO_CART = 'UPDATE_TO_CART'; /*數值相關*/ export const ADD = 'ADD'; export const SUB = 'SUB'; /*標志相關*/ export const FLAG = 'FLAG'; export function addToCart(product,quantity,unitCost){ //我想要保存的商品列表 return { type: ADD_To_CART, payload: {product,quantity,unitCost} } } export function flag(flag){ //根據這個flag標志來判斷是不是加載原有的數據還是重新請求數據 return { type:FLAG, payload:{flag} } }
redux文件夾里面有三個文件,一個是商品的,一個是標志的,一個是把這兩個合並到一起的
// src/reducers/cart-reducer.js import {ADD_To_CART, DELETE_TO_CART,UPDATE_TO_CART} from "../action"; //初始化state const initialState = { cart: [ { product: 'bread 700g', quantity: 2, unitCost: 90 }, { product: 'milk 500ml', quantity: 1, unitCost: 57 } ] } export default function (state = initialState, action){ switch (action.type) { case ADD_To_CART: { return { ...state, cart:[...state.cart,action.payload] } } case DELETE_TO_CART:{ return { ...state, cart:state.cart.filter((item,key)=>{ if(item.product!=action.payload.product){ return item; } }) } } case UPDATE_TO_CART:{ return { ...state, cart:state.cart.map((item,key)=>{ if(item.product == action.payload.product){ return action.payload } else{ return item } }) } } default : return state } }
// src/reducers/flag-reducer.js import {FLAG} from '../action' export default function (state=false,action){ switch (action.type) { case FLAG : return action.payload.flag default : return state } }
import {combineReducers} from 'redux';
import productReducer from './product-reducer';
import cartReducer from './cart-reducer'
import flagSlogn from './flag-reducer'
const allReducer = {
product:productReducer,
shoppingCart : cartReducer,
flagSolgn:flagSlogn
}
const rootReducer = combineReducers(allReducer);
export default rootReducer
然后創建store.js
import {createStore} from 'redux';
import rootReducer from './reducer'
let store = createStore(rootReducer);
export default store
在你的js界面中使用
import React, {Component} from 'react';
import store from '../store/store'
import {addToCart, deleteToCart, updateToCart,flag} from "../store/action";
import {Link} from 'react-router-dom';
class Home extends React.Component {
constructor(props) {
super(props);
this.state = {
cart: [],
}
}
componentDidMount() {if(store.getState().flagSolgn){ //判斷是不是跳轉了的按鈕,點擊了從子界面返回的時候就加載原有的數據
this.setState({
cart:store.getState().shoppingCart.cart
})
}
else{ //沒有點擊,就按照初始化的來
this.setState({
cart:[]
})
store.dispatch(addToCart('Coffee 500mg', 1, 250));
store.dispatch(addToCart('Flour lkg', 2, 440));this.setState({
cart: store.getState().shoppingCart.cart
})
}
}
addProduct(){
store.dispatch(addToCart('Green Tea',5,25));
this.setState({
cart:store.getState().shoppingCart.cart,
})
}
render() {
const {cart} = this.state;
return (
<div>
<ul>
{
cart.map((item,key)=>{
return (
<li key={key}><ul><li>{item.product}</li><li>{item.quantity}</li><li>{item.unitCost}</li></ul></li>
)
})
}
</ul>
<Link to={{pathname:"/HomePage"}}>跳轉子界面</Link>
<div>
<button onClick={this.addProduct.bind(this)}>增加</button>
</div>
</div>
)
}
}
export default Home;
子界面的內容可以隨便寫,畢竟你需要的只是,從子界面返回到父界面,父界面中狀態保持不變的效果,你只需要的是在進入子界面的時候,改變這個flag就好了
import React, {Component} from 'react';
import store from '../store/store'
import {add, flag, sub} from '../store/action'
class HomePage extends React.Component {
constructor(props) {
super(props);
this.state = {
count:0
}
}
componentDidMount() {
store.dispatch(flag(true)); //父界面進入子界面的標志位
}
addCount(){
store.dispatch(add(2));
this.setState({
count:store.getState().product
})
}
subCount(){
store.dispatch(sub(3));
this.setState({
count:store.getState().product
})
}
render() {
const {count} = this.state;
return (
<div>
子界面得到store
{store.getState().shoppingCart.cart[0].product}
<div>
<button onClick={this.addCount.bind(this)}>增加</button>
</div>
<div>
<button onClick={this.subCount.bind(this)}>減少</button>
</div>
<p>數值: {count}</p>
</div>
)
}
}
export default HomePage;
然后你可以在除此以外的其他界面把這個flag變為false,就好了
注:這邊推薦個初學者學習redux的例子,講的很清楚了 https://segmentfault.com/a/1190000011474522?utm_source=tag-newest
