首页 > 解决方案 > Redux 状态在新组件加载时被重置/覆盖

问题描述

我所有的购物车项目都保持在 redux 状态,每当我加载不同的组件时,购物车项目都会被重置。例如,在我的购物车中,我选择了 6 根香蕉,总价为 3 美元。我去水果页面并添加 2 个香蕉。当 Fruits 组件加载时,购物车状态不会以 4 美元的价格总共有 8 根香蕉,而我最终只能以 1 美元的价格得到 2 根香蕉。我认为这是因为在我的 Fruits 页面中,我在从 Firebase 加载产品时设置了状态,我认为因为从 Firebase 我正在设置 Bananas 项目,它没有从我的 redux 购物车中结转的数量。

let itemsRef = db.ref('/productInfo/0/Fruits');

class Fruits extends Component {
    static navigationOptions = {
        title: 'Fruits',
    };

    constructor(props) {
        super(props);
        this.state = {
            items: [],
            filtered: []
        }
        this.handleChange = this.handleChange.bind(this);

    }

    componentDidMount() {
        itemsRef.on('value', (snapshot) => {
            let data = snapshot.val();
            let items = Object.values(data);
            this.setState({items});
            this.setState({
                filtered: items
            });
        });
    }

    componentWillReceiveProps(nextProps) {
        this.setState({
            filtered: nextProps.items
        });
    }

    handleChange(e) {
        let currentList = []
        let newList = []
        if (e.toString() !== "") {
            currentList = this.state.items
            newList = currentList.filter(item => {
                const lc = item.name.toString().toLowerCase()
                const filter = e.toString().toLowerCase()
                return lc.includes(filter)
            })
        } else {
            newList = this.state.items
        }
        this.setState({
            filtered: newList
        });
    }

    render() {
        return (
            <SafeAreaView style ={{flex:1, marginTop:30}}>
                <Searchbar
                    placeholder="Search"
                    onChangeText= {(term) => { this.handleChange(term) }}
                    style = {{marginHorizontal: 20}}
                />
                {
                    this.state.items.length > 0
                        ? <CategoryProductsPage products={this.state.filtered} onPress={this.props.addItemToCart} width = {width}/>
                        : <Text></Text>
                }
            </SafeAreaView>
        );
    }
}


const mapDispatchToProps = (dispatch) => {
    return {
        addItemToCart: (product) => dispatch({ type: 'ADD_TO_CART', payload: product })
    }
}
export default connect(null, mapDispatchToProps)(Fruits);

const styles = StyleSheet.create({
    container: {
        flex: 1,
        alignItems: 'center',
        justifyContent: 'center'
    }
});

理想情况下,我希望我的 redux 购物车状态在我的应用程序中是通用的,除非用户增加或减少数量,否则它不应该改变。我只是通过类别组件页面遇到了这个错误,我相信这是因为我在构造函数和 componentDidMount 中显示 Firebase 产品和代码的方式。我面临的挑战是能够在不改变状态的情况下合并和导入我的 Firebase 产品。

购物车的代码:

import {ADD_TO_CART, REMOVE_FROM_CART, SUB_QUANTITY, ADD_QUANTITY} from './actions';


const initialState = {
    cart: [

    ],
    totalQuantity: 0,
    total: 0.0
};

const updateDeleteProductList = (updateProduct, productList) => {
    return productList.map(product => {
        if (product.name === updateProduct.name) {
            updateProduct.frequency -=1;
            updateProduct.totalPrice = (parseFloat(updateProduct.totalPrice) - product.price).toFixed(2)
            return updateProduct;
        }
        return product;
    });
};

const updateDeleteAllProductList = (updateProduct, productList) => {
    return productList.map(product => {
        if (product.name === updateProduct.name) {
            updateProduct.frequency = 0;
            updateProduct.totalPrice = 0;
            return updateProduct;
        }
        return product;
    });
};

const updateAddProductList = (updateProduct, productList) => {
    return productList.map(product => {
        if (product.name === updateProduct.name) {
            updateProduct.frequency +=1;
            //state.totalPrice = (parseFloat(state.totalPrice) + count).toFixed(2)
            updateProduct.totalPrice = (parseFloat(updateProduct.totalPrice) + product.price).toFixed(2)
            return updateProduct;
        }
        return product;
    });
};




const cartItems = (state = initialState, action) => {
    switch(action.type) {
        case ADD_TO_CART:
                console.log("Cart product screen payload" + JSON.stringify(action.payload))
                let addedItem = action.payload
                //check if the action id exists in the addedItems
                let existed_item= state.cart.find(item=> action.payload.name === item.name)
            console.log("WHAT IS EXISTED ITEM "  + JSON.stringify(existed_item))

                if(existed_item)
                {
                    // addedItem.frequency += 1
                    // addedItem.totalPrice = (parseFloat(addedItem.totalPrice) + action.payload.price).toFixed(2)
                    let updatedProductList = updateAddProductList(action.payload,state.cart);

                    return{
                        ...state,
                        cart: updatedProductList,
                        total: (parseFloat(state.total) + addedItem.price).toFixed(2)
                    }
                }
                else{
                    addedItem.frequency = 1;
                    addedItem.totalPrice = (parseFloat(addedItem.totalPrice) + action.payload.price).toFixed(2)

                    //calculating the total
                    let newTotal = (parseFloat(state.total) + addedItem.price).toFixed(2)

                    return{
                        ...state,
                        cart: [...state.cart, addedItem],
                        total : newTotal
                    }

                }

        case REMOVE_FROM_CART:

            let itemToRemove = action.payload
            console.log("REMOVE ALL" + JSON.stringify(action.payload))
            let new_items = state.cart.filter(item=> action.payload.id !== item.id)
            // let deletedProducts = updateDeleteAllProductList(action.payload, state.cart)
            itemToRemove.totalPrice = 0
                //calculating the total
                let newTotal = state.total - (itemToRemove.price * itemToRemove.frequency )

                //let newTotal = (parseFloat(state.total) - action.payload.totalPrice).toFixed(2)

                return{
                    ...state,
                    cart: new_items,
                    total: newTotal

                }

        case ADD_QUANTITY:
                // let addItem = action.payload
                // console.log('additem is'  + JSON.stringify(addItem))
                // addItem.frequency += 1

            let updatedProductList = updateAddProductList(action.payload,state.cart);
            let newTotalAfterAdd = (parseFloat(state.total) + action.payload.price).toFixed(2)

            return{
                    ...state,
                    cart: updatedProductList,
                    total: newTotalAfterAdd
                }

        case SUB_QUANTITY:
                let lastItemGone = action.payload
            //if the qt == 0 then it should be removed
                if(action.payload.frequency === 1){
                    let new_items = state.cart.filter(item=> action.payload.id !== item.id)
                    lastItemGone.totalPrice = 0
                    let newTotal = (parseFloat(state.total) - action.payload.price).toFixed(2)
                    return{
                        ...state,
                        cart: new_items,
                        total: newTotal
                    }
                }
                else {
                    // addedItem.frequency -= 1
                    let updatedProductList = updateDeleteProductList(action.payload,state.cart);
                    console.log("updatedProductlist" + JSON.stringify(updatedProductList))
                    // const newState = state.set( 'orderProducts', updatedProductList).set('lastOperation', action.type);
                    // return newState;

                    // let newCart = state.cart
                    // for (let i =0; i<newCart.length; i++){
                    //     if(addedItem.name === newCart[i].name){
                    //         newCart[i].frequency -=1
                    //     }
                    // }
                    // console.log("yo new cart is" + JSON.stringify(newCart))

                    let newTotal = (parseFloat(state.total) - action.payload.price).toFixed(2)

                    return{
                        ...state,
                        cart: updatedProductList,
                        total: newTotal
                    }
                }
        default:
            return state;
    }

}

标签: firebasereact-nativeredux

解决方案


推荐阅读