Home > Mobile >  (React) Updating state array does not trigger re-render
(React) Updating state array does not trigger re-render

Time:10-15

Been pulling my hair over this one the whole day and I feel like I've tried pretty much everything, even a dozen StackOverflow answers, to no avail...

tldr; given a specific trigger which happens externally (and just fine) I'm trying to get data from Firestore and update local state (an array) with this new data. Now I know that for React to re-render when updating an array, it will disregard the contents and considers the reference to that array only. The problem is, React seems to not trigger a re-render even when setting the state to a completely new array.

Here is the code:

const Recipe = (irrelevantProps) => {
  // A few other state hooks here, not shown for clarity's sake
  const [ingredients, setIngredients] = useState<IngredientType[]>([]);

  useEffect(() => {
    const getIngredientsDocs = () => {
      return ingredientsRefs.map(async (ingredientRef) => {
        const docRef = doc(firestore, "ingredients", ingredientRef.id);
        const docData = (await getDoc(docRef)).data() as IngredientType;
        return docData;
      });
    };

    Promise.all(getIngredientsDocs()).then((newIngredients) => {
      // I would assume updating the state with a new array would trigger a re-render, but it doesn't
      setIngredients(newIngredients);
    });
  }, [externalTrigger]);

For what it's worth, I'm pretty sure everything else is working as expected.

Any hints, suggestions, tips or downright solutions will be VERY much appreciated.

To whomever may read this, thanks a ton regardless!

CodePudding user response:

I don't have enough reputation points to leave a comment, so I will just do it here (sorry if that's poor etiquette) -- One suggestion I have is to comment out the code within useEffect and just put setIngredients(newIngredients); in its place to see if re-renders work in that scenario.

I've also seen people use a local variable to refer to this outside of a Promise which seems to work though in this case they are using a class component while yours is functional.

CodePudding user response:

Thanks for your help everyone. You were all right in having me test my assumptions. Turns out the new data was fine and the re-rendering was happening too. The problem was a couple levels deeper where a component wasn't updating another state. :facepalm: Lesson learned!

  • Related