Avishai Peretz
Avishai Peretz

Reputation: 38

React Typescript with Redux - Unhandled Rejection (TypeError): Cannot perform 'set' on a proxy that has been revoked

I am try to create React app and connect with Redux but there is an error when i try to update state after i fetch data from service api. Please HELP.

Error description: enter image description here

I share the 3 files that i think is importent to see for solving this issue.

questionReducers.ts file

import {createAction, createReducer} from '@reduxjs/toolkit';
import {fetchInitData} from './questionAPI';
import {AnswerInterface} from "../types/AnswerInterface";
import {Questions} from "../types/Questions";
import {RootState} from "./store";

interface QuestionsState {
    data: Questions,
    status: 'loading' | 'loaded' | 'error'
}

const initialState = {
    data: {
        question: {
            text: '',
            imageURL: ''
        },
        answers: [],
    },
    status: 'loading',
} as QuestionsState

export const appState = (state: RootState) => state;
export const initData = createAction('app/init')
export const addAnswer = createAction<AnswerInterface>('question/addAnswer')


export const questionReducer = createReducer(initialState, (builder) => {
    builder
        .addCase(initData, (state) => {
            fetchInitData().then((res) => {
                state.data = res;
                state.status = 'error';
            }).catch(() => {
                state.status = 'error';
            });
        })
        .addCase(addAnswer, (state, action) => {
            state.data.answers.push(action.payload);
            localStorage.setItem('data', JSON.stringify(state.data));
        })
})

questionAPI.ts file

export function fetchInitData() {
    return fetch('https://example.com/data.json')
        .then(response => response.json())
        .then(response => {
            return response[0];
        })
}

App.tsx file

import React, {useEffect, useState} from 'react';
import styles from './App.module.css';
import { useAppSelector, useAppDispatch } from './app/hooks'
import {initData, appState} from "./app/questionRedeucer";

const App:React.FC<any> = () => {
    const state = useAppSelector(appState);
    const dispatch = useAppDispatch();

    useEffect(() => {
        dispatch(initData());
    });

    return (
        <div className={styles.App}>
            {state.status === 'loading' && <div>Loading...</div>}
            {state.status === 'loaded' && <div>Loaded...</div>}
        </div>
    );
}

export default App;

Upvotes: 0

Views: 415

Answers (1)

markerikson
markerikson

Reputation: 67469

You're trying to do async work in a reducer, which is wrong - a reducer must never contain any async logic!

Technically the localStorage.setItem() is also a side effect and does not belong in a reducer, although in practice it's not a big deal.

Please move that async logic out into a thunk instead:

Upvotes: 1

Related Questions