Search code examples
javascriptreactjsreduxreact-redux

First time implementing redux in react by own. Getting Uncaught typeError


I'm implementing redux to fetch data using free API. Could anybody please explain why I'm getting this error and what can be the solution for this.

action.js

export const tesla = () =>{
    return (dispatch) => {
        dispatch({
            type:'tesla',
            payload:
            "https://newsapi.org/v2/everything?q=tesla&from=2022-07-17&sortBy=publishedAt&apiKey=b1e1719ca0724ff9bd9dab0645884e9a"
        })
    }
}

export const business = ()=>{
    return (dispatch)=>{
        dispatch({
            type:'business',
            payload:
            "https://newsapi.org/v2/top-headlines?country=us&category=business&apiKey=b1e1719ca0724ff9bd9dab0645884e9c"
        })
    }
}

ApiReducer.js:

import React,{useState} from "react";
import axios from "axios";

const ApiReducer = (state=0,action) =>{
    const type=action.type;
    const [eror,setEror] = useState({});
    const data = axios.get(action.payload).
    then(data=>console.log(data)).catch(
        error=>{
            console.log(error);
            setEror(error);
        }
    );
    if(eror.length!==0) return eror;
    return data;
}

export default ApiReducer;

CombineReducer.js:

import { combineReducers } from "@reduxjs/toolkit";
import ApiReducer from "./ApiReducer";

const CombineReducer = combineReducers({
    value:ApiReducer
});

export default CombineReducer;

Store.js

import { configureStore } from "@reduxjs/toolkit";
import thunk from 'redux-thunk';
import reducers from "../reducers/CombineReducer";

const Store = configureStore({
    reducer:reducers,
    preLoadedState:{},
    middleware:[thunk]
});

export default Store;

exportAction.js

export * as actions from './actions/action';

Rexercise.js

import React,{useState} from "react";
import {useSelector} from 'react-redux';
import { useDispatch } from "react-redux/es/exports";
import { actions } from "./redux";


const Rexercise = ()=>{
    const [data,setData] = useState({});
    data = useSelector(state=>state.value);
    const dispatch = useDispatch();
    
    const Tesla = ()=>{
        setData(dispatch(actions.tesla()));
    }
    const Business = ()=>{
        setData(dispatch(actions.business()));
    }

    return(
            <div class="container">
                <h1>Hello World</h1>
                <button class="btn btn-primary" onClick={()=>Tesla()}>Tesla</button>
                <button class=" mx-2 btn btn-success" onClick={()=>Business()}>Business</button>

                <div className="article text-primary">
                    {data}
                </div>
            </div>
            
    )
}

export default Rexercise;

I provided the store in index.html for this App. The error I'm getting:

Uncaught TypeError: Cannot read properties of null (reading 'useState') at useState (react.development.js:1622:1)

at ApiReducer (ApiReducer.js:6:1)
at redux.js:468:1
at Array.forEach (<anonymous>)
at assertReducerShape (redux.js:466:1)
at combineReducers (redux.js:531:1)
at ./src/components/redux/reducers/CombineReducer.js (CombineReducer.js:4:1)
at options.factory (react refresh:6:1)
at __webpack_require__ (bootstrap:24:1)
at fn (hot module replacement:62:1)

Solution

  • Your ApiReducer is not a reducer. You cannot call asynchronous methods in there and you can also not use useState in there. On top of that, you are writing a style of Redux here that is >3 years outdated and over 4 times the code modern Redux would be.

    Please follow the official Redux tutorial - whatever resource you are following right now is giving you outdated and probably outright wrong instructions.