Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

recoil actions in useEffect #44

Open
SecretUnicorn opened this issue May 16, 2023 · 1 comment
Open

recoil actions in useEffect #44

SecretUnicorn opened this issue May 16, 2023 · 1 comment

Comments

@SecretUnicorn
Copy link

function useTeams() {
  const [teamState, setTeamState] = useRecoilState(teamsAtom);

  function init(teams) {
    setTeamState(teams.map(t => ({
      ...t,
      answered: false,
      already_answered: false,
    })));
  }

  function teamAnswered(teamId) {
    setTeamState(teamState.map(t => ({
      ...t,
      answered: t.id === teamId,
    })));
  }

  return [teamState, { init, teamAnswered }];
useEffect(() => {
    if (lastMessage && lastMessage.data) {
          teamAnswered(data.data)
    }
  }, [lastMessage, teamAnswered]);

I want to change my recoil state in a useEffect. My linter tells me to add the "setTeam" function to the dep list of the useEffect. But when I use setTeam, team changes and setTeam does too which causes the useEffect to trigger endlessly. Is this intended or am I using the hook wrokng? Any help would be apreciated

@suren-atoyan
Copy link
Owner

@SecretUnicorn

two important things to improve here:

  1. when you use setState and you need to refer to the previous state use this method:
const [count, setCount] = useState(0);

...
function increment() {
  setCount(prevCount => prevCount + 1);
}

This will help you to make increment function have no dependencies (we do not consider setCount).

In your case it should be something like this:

function teamAnswered(teamId) {
  setTeamState(teamState => teamState.map(t => ({
    ...t,
    answered: t.id === teamId,
  })));
}
  1. use useCallback
const teamAnswered = useCallback((teamId) => {
  setTeamState(teamState => teamState.map(t => ({
    ...t,
    answered: t.id === teamId,
  })));
}, [setTeamState]);

let me know if this helps

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants