ataravati
ataravati

Reputation: 9155

Formik's setFieldValue doesn't work with value coming from Context API

I'm using AWS Amplify and Formik in my React Native app. There's a screen in which a list of members will be displayed, and when the screen is loaded, the current user will be added by default to the list. Here's what I had before and works perfectly (I can see the current user in the list on the screen).

  useEffect(() => {
    if (values.members.length === 0) {
       Auth.currentAuthenticatedUser().then(user => {
         const owner: Member = {
           id: user.attributes.sub,
           name: user.attributes.name,
         };

         setFieldValue('members', [owner]);
       });
    }
  }, []);

But, then, I created a UserContext and decided to replace the call to the amplify function Auth.currentAuthenticatedUser() with the user coming from the UserContext. Here's the new code:

  const { user } = useContext(UserContext);

  useEffect(() => {
    if (values.members.length === 0) {
      const owner: Member = {
        id: user.attributes.sub,
        name: user.attributes.name,
      };

      console.log("Owner", owner); // This displays the current user in the console

      setFieldValue('members', [owner]);
    }
  }, []);

As I've commented in the code, the console.log() displays the current user, so the UserContext is working correctly, but for some reason setFieldValue doesn't work. Does anyone have any idea why this might be happening?

UPDATE:

I figured if I put setFieldValue() in the second code inside a setTimeout it works. But, in that case, shouldn't it also work if I changed useEffect(() => {}, []) to useEffect(() => {}, [user])?

Upvotes: 1

Views: 6320

Answers (2)

gdh
gdh

Reputation: 13692

You issue is because of an existing formik issue. So till it is fixed, just live with setTimeout or the solution you have mentioned.

Also see some of the other alternatives mentioned in the same link if it is useful.

Upvotes: 4

ataravati
ataravati

Reputation: 9155

Here's what I ended up doing. I'm posting this as an answer, but I'm still looking for an answer as to why this even happens.

  const { user } = useContext(UserContext);
  const [owner, setOwner] = useState(null as Member | null);

  useEffect(() => {
    if (values.members.length === 0) {
      setOwner({
        id: user.attributes.sub,
        name: user.attributes.name,
      });
    }
  }, []);

  useEffect(() => {
    setFieldValue('members', [owner]);
  }, [owner]);

Upvotes: 0

Related Questions