Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

React Hooks, useReducer not able to get state

I'm making a simple component try to make use of the useEffect and useReducer hooks. Everything seems to be working fine except that none of the items in the array actually make their way into the component. I've done some console.log statements inside the various functions and I can see that the API call is successful and that the data is available in the scope of the function under events. However, all that renders is an empty box. My code is:

import React, { useReducer, useEffect } from "react";
import "./App.css";

const  App = () => {
  const [events, dispatch] = useReducer(
      (state, action) => { switch (action.type) {
          case "fetchEvents":
              state = [ ...state, action.data];
             return state;

            case "removeEvent":
              return state.filter((_, idx) => idx !== action.idx);

            default:
                console.log(state);
              return state;
        }
      },
  []);

  useEffect(async () => {
    const response = await fetch("https://easynode-veohkvapci.now.sh/api/test");
    const data = await response.json();
    dispatch({type: "fetchEvents", data});
  },[]);

  console.log(events, 'log events');

  return (
      <div>
          {events.map((event, idx) => (
              <div key={event.event_url} style={{ border: "solid" }}>
                  <p>{event.name}</p>
                  <p>{event.date}</p>
                  <p>{event.description}</p>
                <button onClick={() => dispatch({ type: "removeEvent", idx})}>Remove Event</button>
              </div>
          ))}
      </div>
  );
};

export default App;

Should I maybe be calling useEffect inside of useReducer instead? I might be screwing something up that's supposed to happen in an async fashion.

like image 894
Michael Porter Avatar asked Dec 05 '25 11:12

Michael Porter


1 Answers

The data you get in return from your request is an array, so you need to make sure you spread that as well in the fetchEvents case in your reducer.

const [events, dispatch] = useReducer((state, action) => {
  switch (action.type) {
    case "fetchEvents":
      state = [...state, ...action.data];
      return state;

    case "removeEvent":
      return state.filter((_, idx) => idx !== action.idx);

    default:
      return state;
  }
}, []);
like image 149
Tholle Avatar answered Dec 08 '25 00:12

Tholle



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!