Search code examples
reactjsnext.jsuse-effect

JSON.stringfy(ArrayData) change is not being subscribed in UseEffect in Nextjs


import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
import {
  faSearch,
  faAmbulance,
  faAnchor,
  faPlus,
  faFloppyDisk,
} from '@fortawesome/free-solid-svg-icons';
import {
  Input,
  Table,
  Button,
  Modal,
  ModalBody,
  ModalHeader,
  ModalFooter,
  FormGroup,
  Label,
  Col,
  Row,
} from 'reactstrap';
import { useState, useEffect } from 'react';
import { useSelector, useDispatch } from 'react-redux';
export default () => {
  const dispatch = useDispatch();
  //receive the value from api const annexItems = useSelector((state) => state.d03reducer.annexItem)

  //filter the value where aanexID===5 const inclusion = annexItems?.filter(annex => { return (annex.itemType === "IN" && annex.annexID === '5') });

  console.log('inclusion', inclusion);

  //for setting the value in input fields for dynamic inclusion
  const [inclustionValue, SetinclusionValue] = useState([]);

  //use for summin the inclusionvalue
  const [inclusionValueSum, SetinclusionValueSum] = useState(0);
  const inclusionHandleChange = (e) => {
    const { name, value } = e.target;

    console.log('value on handlechange', value);

    var inclusionItem = inclustionValue.find((va) => va.itemID === name);
    console.log('item', inclusionItem);
    if (inclusionItem?.itemID === name) {
      //  inclusionItem.itemID = name;
      if (value === '') {
        value = 0;
      } else {
        value = value;
      }
      inclusionItem.value = value;

      console.log('inclusionValue after Update', inclustionValue);
    } else {
      if (value === '') {
        value = 0;
      } else {
        value = value;
      }
      SetinclusionValue([...inclustionValue, { itemID: name, value: value }]);
    }

    console.log('inclusion value inside', inclustionValue);
    // return inclustionValue;
  };

  //this does not work when i update the existing value in the array but works when the array value get changed
  useEffect(() => {
    const Sum = inclustionValue.reduce((acumulator, object) => {
      return parseFloat(acumulator) + parseFloat(object.value);
    }, 0);

    SetinclusionValueSum(Sum);
    // console.log("i am being called");
    console.log('sum in useeffect', Sum);
    console.log('sum after set in inclusionSum', inclusionValueSum);
  }, [JSON.stringify(inclustionValue)]);
  console.log('inclusion value', inclustionValue);

  const [snumber, setSnumber] = useState(1);

  return (
    <div>
      <div className='form card col-xs-12 col-sm-12 col-md-12 col-lg-9 col-xxl-9'>
        <Col className='card-header'>Annex 5</Col>
        <div className='card'>
          <Col className='card-body'>
            <Col className='card'>
              <div className='card mt-2'>
                <div className='card-header'>Inclusion(IN)</div>
                <div className='card-body'>
                  <Table bordered>
                    <tbody>
                      {inclusion?.map((annexItem, index) => {
                        return (
                          <tr key={index}>
                            <td>{index + 1}</td>
                            <td>{annexItem.itemDescNep}</td>
                            <td>
                              <Input
                                type='text'
                                className='form-control'
                                name={annexItem.itemID}
                                onChange={inclusionHandleChange}
                              ></Input>
                            </td>
                          </tr>
                        );
                      })}
                      <tr>
                        <td>{inclusion?.length + 1}</td>
                        <td>Total:(1 to {inclusion?.length})</td>
                        <td>
                          <Input
                            type='text'
                            className='form-control'
                            value={inclusionValueSum}
                          ></Input>
                        </td>
                      </tr>
                    </tbody>
                  </Table>
                </div>
              </div>
            </Col>
          </Col>
        </div>
      </div>
    </div>
  );
};

when I change the value in input fields the value do reflect in handlechanger but useEffect get called only when there is change in array length. I want to use useEffect also when the inclustionValue Array value updated too


Solution

  • Try to change your inclusionHandleChange function like this:

    const inclusionHandleChange = (e) => {
      const { name, value } = e.target;
      const newValue = value === '' ? 0 : value;
    
      var inclusionItem = inclustionValue.find((va) => va.itemID === name);
      if (inclusionItem) {
        // Update existing item
        inclustionValue.find((va) => va.itemID === name).value = newValue
        // Triggers data refresh
        SetinclusionValue([ ...inclustionValue ])
      } else {
        // Add new inclusion value
        SetinclusionValue([ ...inclustionValue, { itemID: name, value: newValue }]);
      }
    };