[英]How to update same redux state on two different components simultaneously?
I have a React Native scenario in which I have two components, one is a textInput
and the other is a SVG
drawing.我有一个 React Native 场景,其中我有两个组件,一个是textInput
,另一个是SVG
绘图。 By filling out the textInput
and pressing a button, the text is inserted as a data instance to an array stored in a redux state using a dispatch
action (let's call it textListState
).通过填写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) } />
)
Now, the SVG
component updates all the features' fill color stored in the textListState
using a function (eg setFillColor
).现在, SVG
组件使用 function(例如setFillColor
)更新存储在textListState
中的所有特征的填充颜色。 This is done inside a useEffect
hook with a dependency set to a prop (eg propA
).这是在useEffect
挂钩中完成的,其依赖项设置为 prop(例如propA
)。
Now the problem is that I need to add textListState
as a dependency to the useEffect
because I want the newly entered text from the textInput
to be included in the SVG
component.现在的问题是我需要添加textListState
作为useEffect
的依赖项,因为我希望将textInput
中新输入的文本包含在SVG
组件中。 But by doing so, I am creating an infinite loop, because the setFillColor
also updates the textListState
.但是通过这样做,我正在创建一个无限循环,因为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>
)
How can I achieve to be able to add the newly inserted text to the SVG
component without creating an infinite loop?如何在不创建无限循环的情况下将新插入的文本添加到SVG
组件?
The redux action 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 }
};
The redux reducer 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;
if you want to trigger useEffect only when new text is added then use textListState.length
instead of textListState
in dependency list.如果您只想在添加新文本时触发 useEffect ,则在依赖项列表中使用textListState.length
而不是textListState
。
If you want to do it both on update and insert (ie you want to fire even when text is updated in input) then use a boolean flag textUpdated
in textListState
and keep toggling it whenever there is a update or insert and use textListState.textUpdated
in dependency list.如果您想在更新和插入时都执行此操作(即即使在输入中更新文本时也想触发),则在textListState
中使用 boolean 标志textUpdated
并在有更新或插入时继续切换它并使用textListState.textUpdated
依赖列表。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.