1

I discovered that my reducer was being called twice for each dispatch after noticing that some of my code's functionality was broken. Now I found out that it is due to the <StrictMode>. I would hate to remove this. If I turn on my debugger (StrictMode still there), I get this error

  Cannot update a component (`ForwardRef(TouchRipple)`) while rendering a different component 

As you can see, I build my provider according to the reducer-dispatch pattern

I'm posting the code, with very simple naming.

types

export type ValueState = {
    value: string | null;
};


export enum AcionType {
    SetValue,
}
export interface SetValue {
    type: AcionType.SetValue;
    value: string | null;
}

export type ValueActions = SetValue;

export type ValueDispatch = Dispatch<ValueActions>;

export type ValueContextState = {
    state: ValueState;
    dispatch: ValueDispatch;
};

reducer

export const valueReducer = (state: ValueState, action: ValueActions): ValueState => {
    console.log("reducer") // getting called two times!!;
    switch (action.type) {
        case AcionType.SetValue:
            return {
                ...state,
                value: test(action.value),
            };
        default:
            return state;
    }
};
const test = (value: string | null) => {
    debugger;
    return value;
};

Context

export const ValueContext = createContext<ValueContextState>({
    state: getDefaultState(),
    dispatch: () => {},
});

    export const ValueProvider = ({ children }: Props) => {
        const [state, dispatch] = useReducer<React.Reducer<ValueState, ValueActions>>(valueReducer, getDefaultState());
    
        const [contextValue, setContextValue] = useState<ValueContextState>({
            state,
            dispatch,
        });
    

        useEffect(() => {
            setContextValue((contextValue: ValueContextState) => ({
                ...contextValue,
                state,
            }));
        }, [state]);
    
        return <ValueContext.Provider value={contextValue}>{children}</ValueContext.Provider>;
    };
    
    function getDefaultState(): ValueState {
        return {
            value: null,
        };
    }
    
    type Props = {
        children: React.ReactNode;
    };

customHook

export const useValues = () => {
    const { state, dispatch } = useContext(ValueContext);

    const setValue = useCallback(
        (value: string | null) => {
         console.log("dispatch") // getting called once!
            dispatch({
                type: AcionType.SetValue,
                value: value,
            });
        },
        [dispatch],
    );

    return {
        value: state.value,
        setValue: setValue,
    };
};

Using Provider

<Routes>
            <Route
                index
                element={
                    <ValueProvider>
                        <Values />
                    </ValueProvider>
                }
            />
        </Routes>

making dispatch

 export const Value = () => {
        const { setValue } = useValues();
        return <InputComponent onChange={(e) => setValue(e.target.value)} />;
    };
9
  • 1
    Could this be it: stackoverflow.com/questions/48846289/… ? It is quite common reason for such problems. You can use the most upvoted answer to test it out. Commented Jul 19, 2022 at 7:36
  • I cant believe it. I sat loosely 3 days at the measures. Should that be turned off? Is it good Commented Jul 19, 2022 at 7:40
  • Well, there is a debate whether it should be turned off or not. In my view it is fine to be kept on if you can be sure that the double render problem is caused by that 'extra caution measure'. Its intention is good but it can cause confusion. So, try taking it off to see if it fixes your problem. If it does, great. Then you know there is nothing else wrong with it. Double render only happens in dev environment, so when running it in production mode, this shouldn't happen anymore if it was because of this extra measure. So, take it off, see if it works and put it back on in my opinion. Commented Jul 19, 2022 at 7:58
  • Could you please take a look here. stackoverflow.com/a/73004815/17682036 Do you know why the functional solution is not working? Hope it is not to random Commented Jul 19, 2022 at 8:01
  • @axordahaxor i completely reformulated my question Commented Jul 19, 2022 at 9:05

0

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.