[英]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.