在上一篇文章中说过了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