0

I have a group of functions that are responsible for adding and removing sections from my form in my app. I use a counter (subjectAddressCounter) in my state that keeps track of the iteration of the section being added. This works as expected when the user clicks the buttons to add and remove the sections, however when I call the addSection() function on init in a form mapping function generateAdditiveFormKeys() the counter jumps from 0 to 2 and so it only calls the callback function in the useEffect responsible for adding the section one time, which means my form doesn't build correctly.

So to be clear. I expect that for each time the function is called the counter will iterate by one, but what's happening on init is that my function is called twice, but in the useEffect the counter goes from 0 to 2 instead of 0, 1, 2. This causes my callback function to only be called once and then the sections are out of sync.

What am I doing wrong?

Please see the relevant code below. Also, is there a way to simplify this pattern so I don't need to use three functions just to add or remove a section?

const FormGroup = prop => {
  const [subjectAddressCounter, setSubjectAddressCounter] = useState(0);

  const addValues = () => {
    const newSection = subjectAddressCopy.map(copy => { 
      const clone = {
        ...copy,
        prop: copy.prop = `${copy.prop}_copy_${subjectAddressCounter}`,
        multiTypes: copy.multiTypes ? copy.multiTypes.map(multi => {
          const cloneMultiTypes = {
            ...multi,
            prop: multi.prop = `${multi.prop}_copy_${subjectAddressCounter}`,
          };
          return cloneMultiTypes;
        }) : null,
      };
      return clone;
    });

    ...
  };

  const removeValues = () => {
    ...
  }

  const prevSubjectAddressCounterRef = useRef<number>(subjectAddressCounter);
  useEffect(() => {
    prevSubjectAddressCounterRef.current = subjectAddressCounter;

    if (prevSubjectAddressCounterRef.current < subjectAddressCounter) {
      // call function to addValues
      // this is only being called once on init even though subjectAddressCounter starts at 0 and goes to 2
      addValues();
    }

    if (prevSubjectAddressCounterRef.current > subjectAddressCounter) {
      // call function to removeValues
      removeValues();
    }


  }, [subjectAddressCounter]);


  const addSection = section => {
    if (section.section === SectionTitle.subjectAddress) {
       // this gets called twice on init
      setSubjectAddressCounter(prevCount => prevCount + 1);
    }
  };

  const removeSection = section => {
    if (section.section === SectionTitle.subjectAddress) {
      setSubjectAddressCounter(prevCount => prevCount - 1);
    }
  };

const generateAdditiveFormKeys = reportResponse => {
  const {
    entity_addresses_encrypted: entityAddressesEncrypted, // length equals 3
  } = reportResponse; 
  let additiveAddresses = {};
  if (entityAddressesEncrypted?.length > 1) {
    entityAddressesEncrypted.forEach((entityAddress, i) => {
      if (i === 0) return;
      if (subjectAddressCounter < entityAddressesEncrypted.length - 1) {
        addSection({ section: SectionTitle.subjectAddress }); 
      }
      const keysToAdd = {
        [`question_11_address_copy_${i - 1}`]: entityAddress.address,
        [`question_12_city_copy_${i - 1}`]: entityAddress.city,
        [`question_13_state_copy_${i - 1}`]: entityAddress.state,
        [`question_14_zip_copy_${i - 1}`]: entityAddress.zip,
        [`question_15_country_copy_${i - 1}`]: entityAddress.country,
      };
      additiveAddresses = { ...additiveAddresses, ...keysToAdd };
    });
  }
 ...
 }

return (
   ... 
   button onClick={() => addSection(form)}

   button onClick={() => removeSection(form)}

 )

}
London804
  • 1,072
  • 1
  • 22
  • 47
  • After defining state (e.g. `const [mystate, setMystate] = useState('')`), pass state to `useRef` (e.g. `const myref = useRef(mystate)`). In a `useEffect` block with `mystate` as dependency, put `myref.current = mystate;` . Now, you have `mystate` as current value and `myref.current` as previous value anywhere. – Morteza M Jul 12 '22 at 21:11
  • Yes, this is basically the code that I posted, the problem is onInit my myState variables jumps from 0 to 2 instead of moving up incrementally. – London804 Jul 12 '22 at 21:24

0 Answers0