繁体   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