Why when following the quick start for easy peasy is my state not changing in Nextjs?

674 Views Asked by At

I was trying to use easy peasy for global state management within a nextjs app and was running into problems where the state would only update when I changed pages. I thought maybe I didn't quite grasp what I was doing so I decided to try a quick app with the quick start guide: https://easy-peasy.vercel.app/docs/tutorials/quick-start.html

Setting all this up nothing is happening when I click the button. If I make a change within the code and save it then all the changes happen when it hot reloads.

Does anyone have any idea why this is and how I fix it? I thought it might be nextjs but I just tested it with react and that's not working either. I must be missing some understanding of how this is supposed to work. In a tutorial I was following it worked just fine and cloning it also works. I have no idea when I try and create my own project with the same code its why it's not updating right away.

edit: I don't know why I didn't just share the repo. Here it is: https://github.com/Kyle-Kroger/easy-peasy-broken

edit 2: I tried to get Traversy Media's easy-peasy tutorial to work updating things for v5 and that does the same thing. Nothing updates when clicked but if I edit the code it will update the state on reload. I'm going to try on another computer in the morning. https://github.com/Kyle-Kroger/traversy-media-easy-peasy-broken

edit 3: I think I might have figured it out. I wonder if it has something to do with version 18 of react. That is the only thing that is different between the repo I cloned that works and mine. Going to see how to use create-react-app with an older version and see if that will work.

edit 4: Well after many hours I figured out the problem. Something in react version 18 broke something with how easy-peasy works. Going back to 17 makes things work.

Here is all my code:

//store.js
import { createStore, action } from "easy-peasy";

export const store = createStore({
  todos: [],
  addTodo: action((state, payload) => {
    state.todos.push({ text: payload, done: false });
  }),
});
//body.js
import { useStoreState } from "easy-peasy";

const Body = () => {
  const todos = useStoreState((state) => state.todos);
  return (
    <>
      <p onClick={() => console.log(todos)}>Some more text to click</p>
      <ul>
        {todos.map((todo) => (
          <li key={todo.text}>{todo.text}</li>
        ))}
      </ul>
    </>
  );
};

export default Body;
//title.js
import { useStoreActions } from "easy-peasy";
import { useState } from "react";

const Title = () => {
  const addTodo = useStoreActions((actions) => actions.addTodo);
  const [value, setValue] = useState("");

  return (
    <>
      <input onChange={(e) => setValue(e.target.value)} value={value} />
      <button onClick={() => addTodo(value)}>Add Todo</button>
    </>
  );
};

export default Title;
_app.js
import "../styles/globals.css";
import { StoreProvider } from "easy-peasy";
import { store } from "../lib/store";

function MyApp({ Component, pageProps }) {
  return (
    <StoreProvider store={store}>
      <Component {...pageProps} />
    </StoreProvider>
  );
}

export default MyApp;
//index.js
import Body from "../components/body";
import Title from "../components/title";

export default function Home() {
  return (
    <div>
      <Title></Title>
      <Body></Body>
    </div>
  );
}
2

There are 2 best solutions below

0
On

I was also having trouble with the update. Interestingly, I changed the StoreProvider from index.js to app.js and it works.

0
On

Removing

   <React.StrictMode></React.StrictMode>

from index.js fixes the issue on React 18. Not a real solution but a workaround till Someone fixes it.