簡體   English   中英

如何同時在兩個不同的組件上更新相同的 redux state?

[英]How to update same redux state on two different components simultaneously?

我有一個 React Native 場景,其中我有兩個組件,一個是textInput ,另一個是SVG繪圖。 通過填寫textInput並按下按鈕,文本作為數據實例插入到存儲在 redux state 中的數組中,使用dispatch操作(我們稱之為textListState )。

//TEXT INPUT COMPONENT
//this code is just for presentation. it will cause errors obviously
const dispatch = useDispatch();
const submitHandler = (enteredText) => {
    dispatch(submitData(enteredText))
};

return(
    <TextInput ...... />
    <TouchableOpacity onPress={() => submitHandler(enteredText) } />
)

現在, SVG組件使用 function(例如setFillColor )更新存儲在textListState中的所有特征的填充顏色。 這是在useEffect掛鈎中完成的,其依賴項設置為 prop(例如propA )。

現在的問題是我需要添加textListState作為useEffect的依賴項,因為我希望將textInput中新輸入的文本包含在SVG組件中。 但是通過這樣做,我正在創建一個無限循環,因為setFillColor也會更新textListState

//SVG COMPONENT
const [textList, setTextList] = useState([]);
const textListState = useSelector(state => state.textListState);

const dispatch = useDispatch();
const setFillColor= useCallback((id, fill) => {
    dispatch(updateFillColor(id, fill))
}, [dispatch]);

useEffect(() => {
    //INFINITE LOOP BECAUSE textListState  KEEPS UPDATING WITH setFillColor
    const curTextList = [];

    for (const [i, v] of textListState.entries()) {
        setFillColor(5, "white")

        curTextList.push(
            <someSVGComponent />
        )
    }
    setTextList(curTextList);
}, [props.propA, textListState])

return(
    <G>
        {textList.map(x => x)}
    </G>
)

如何在不創建無限循環的情況下將新插入的文本添加到SVG組件?


編輯:

redux 動作

export const UPDATE_TEXT = "UPDATE_TEXT";
export const SUBMIT_DATA = "SUBMIT_DATA";

export const updateFillColor = (id, fill) => {
    return { type: UPDATE_TEXT, id: id, fill: fill }
};

export const submitData= (text) => {
    return { type: SUBMIT_DATA, text: text }
};

redux減速機

import { TEXT } from "../../data/texts";
import { UPDATE_TEXT } from "../actions/userActions";
import { INSERT_TEXT } from "../actions/userActions";

// Initial state when app launches
const initState = {
    textListState: TEXT
};

const textReducer = (state = initState, action) => {
    switch (action.type) {
        case INSERT_TEXT :
            return {
                ...state,
                textListState: [
                    ...state.textListState,
                    action.text
                ]
            }
        case UPDATE_TEXT :
            const curText = state.textListState.filter(text => text.id === action.id)[0];

            return {
                ...state,
                textListState: [
                    ...state.textListState.slice(0, curIndex), //everything before current text
                    curText.fill = action.fill,
                    ...state.textListState.slice(curIndex + 1), //everything after current text
                ]
            }

        default:
            return state;
    }
};

export default textReducer;

如果您只想在添加新文本時觸發 useEffect ,則在依賴項列表中使用textListState.length而不是textListState

如果您想在更新和插入時都執行此操作(即即使在輸入中更新文本時也想觸發),則在textListState中使用 boolean 標志textUpdated並在有更新或插入時繼續切換它並使用textListState.textUpdated依賴列表。

暫無
暫無

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

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