簡體   English   中英

React Native Redux 組件不會在 Redux 狀態更改時重新渲染

[英]React Native Redux Component not rerendering on Redux State Change

我正在研究 React Native 中的購物籃組件。 購物籃的內容和價格保存在全球 redux 商店中。 當用戶選擇一個項目時,將調度一個操作以將該項目添加到購物籃並更新購物籃總價格。

但是,UI 不會在此全局狀態更改上得到更新。

我的減速機

const INITIAL_STATE = {
basket: [],
basketPrice: 0,
};

const mainReducer = (state = INITIAL_STATE, action) => {
    const stateCpy = state;
    switch (action.type) {
        case 'SET_BASKET':
            stateCpy.basket = action.payload
            return stateCpy;
        case 'ADD_TO_BASKET':
            stateCpy.basket.push(action.payload)
            return stateCpy
        case 'REMOVE_FROM_BASKET':
            let tempItems = stateCpy.basket
            for (var x = 0; x < stateCpy.basket.length; x++) {
                if (stateCpy.basket[x]._id === action.payload) {
                    tempItems.splice(x, 1)
                    break;
                }
            }
            stateCpy.basket = tempItems
            return stateCpy
        case 'SET_BASKET_PRICE':
            stateCpy.basketPrice = action.payload
            console.log(stateCpy.basketPrice)
            return stateCpy
        default:
            return state
    }
};

export default mainReducer

我的行動

const setBasket = basket => ({
    type: 'SET_BASKET',
    payload: basket,
});
const addToBasket = item => ({
    type: 'ADD_TO_BASKET',
    payload: item,
});
const removeFromBasket = item_id => ({
    type: 'REMOVE_FROM_BASKET',
    payload: item_id,
});

const setBasketPrice = price => ({
    type: 'SET_BASKET_PRICE',
    payload: price,
});

export default actions = {
    setBasket,
    addToBasket,
    removeFromBasket,
    setBasketPrice
}

我的 UI 組件

... 

import { useSelector, useDispatch } from 'react-redux'

export const RestaurantView = ({ navigation, route }) => {
    const basket = useSelector((state) => state.basket)
    const basketPrice = useSelector((state) => state.basketPrice)
    
    const dispatch = useDispatch()

...

function calcBasketPrice(){
        let tempBasketPrice = 0
        basket.forEach(element => {
            tempBasketPrice += element.price
        });
        return tempBasketPrice
        
    }

    function addToBasket(item) {
        dispatch(actions.setBasketPrice(calcBasketPrice() + item.price))
        dispatch(actions.addToBasket(item))
    }


return ( <View>
    <ItemCard onPress={addToBasket}> </ItemCard>
    <Text style={{ textAlign: "right", padding: 15, fontSize: 20 }}> {basketPrice}</Text>
</View>)

}

當將 basketPrice 記錄到 reducer 中的控制台時,它會在每次按下/發送時記錄正確的更新值,但 UI 中沒有任何變化。 當進行本地狀態更改以強制重新渲染時,它會使用全局存儲中的正確值進行渲染。

您的stateCpy變量實際上不是副本,而只是對state的引用-因此您的減速器實際上是在修改舊的 redux 狀態而不是創建新狀態。

由於這是一種非常過時的 Redux 風格,並且在現代 Redux createSlice reducers 中修改state是完全可以的,我建議你不要在遺留 Redux 中修復這個問題,而是看看現代 Redux - 這也更少錯誤 -很容易,大約是您使用舊版 Redux 編寫的代碼的 1/4。 重寫你的 reducer 不是很多工作,從長遠來看,你將真正受益於(自 2019 年以來)新風格。

看看官方的 Redux 教程

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM