Unable to push data to array and eventually update the state in react js

Viewed 55

My code:

import "./styles.css";
import { useState, useEffect } from "react";
import _ from "lodash";

export default function App() {
  const [uncheckedColArr, setUncheckedColArr] = useState([]);

  const updateFilterValue = (columnName, fieldValue, checked) => {
    let tempUncheckedColArr = [...uncheckedColArr];
    if (tempUncheckedColArr[columnName] === undefined) {
      tempUncheckedColArr[columnName] = [];
    }

    //trying to toggle value in the array
    tempUncheckedColArr[columnName] = _.xor(tempUncheckedColArr[columnName], [
      fieldValue
    ]);

    console.log("fieldValue", fieldValue);
    console.log("tempUncheckedColArr", tempUncheckedColArr);
    console.log("uncheckedColArr1", uncheckedColArr);

    //trying to update uncheckedColArr with new data
    setUncheckedColArr(tempUncheckedColArr);

    console.log("tempUncheckedColArr", tempUncheckedColArr);
    console.log("uncheckedColArr2", uncheckedColArr);
  };

  useEffect(() => {
    console.log("useEffect", uncheckedColArr);

    //currently here I am just trying to console log
    //but I will be filtering those data which do not possesses
    //values fromf this uncheckedArr in respective col.
    uncheckedColArr.map((col) => console.log("col", col));
  }, [uncheckedColArr]);

  const handleChange = (e) => {
    const fieldValue = e.target.value;
    const checked = e.target.checked;
    const columnName = e.target.getAttribute("data-col-name");
    updateFilterValue(columnName, fieldValue, checked);
  };

  return (
    <div className="App">
      <input
        type="checkbox"
        defaultChecked={true}
        value="1"
        name={`checkbox[]`}
        data-col-name="building_number"
        onChange={handleChange}
      />
      <label>Building Number</label>

      <input
        type="checkbox"
        defaultChecked={true}
        value="123"
        name={`checkbox[]`}
        data-col-name="unit_number"
        onChange={handleChange}
      />
      <label>Unit Number 1</label>

      <input
        type="checkbox"
        defaultChecked={true}
        value="123"
        name={`checkbox[]`}
        data-col-name="unit_number"
        onChange={handleChange}
      />
      <label>Unit Number 2</label>
    </div>
  );
}

Let me break this code:

  1. I click on checkbox, and I want to toggle this value into an array. Basically, there could be multiple checkbox on multiple columns. So onChange action of checkbox I am trying to trigger updateFilterValue function

  2. On this function, what I am trying is that, I want to store these unchecked values in an array, and expecting output is something like:

[
 'building_number': ['1', '2'],
 'unit_number': ['123', '456']
]

So, that later, I could filter data which don't possess these values on respective columns. In case of checked, i will remove data from this uncheckedColArr and in case of unchecked, I will add this value to uncheckedColArr

But, currently I am not able to update uncheckedColArr and obtain the expected result as mentioned above. Let me know, if you don't understand something.

Also, here is the code sandboxlink: https://codesandbox.io/s/angry-sky-uqjo44?file=/src/App.js

1 Answers

Here is the updated code. First you cannot store values like that.

[
 'building_number': ['1', '2'],
 'unit_number': ['123', '456']
]

It's invalid.

Instead store in an object as shown in below code.

import "./styles.css";
import { useState } from "react";
import _ from "lodash";

export default function App() {
  const [uncheckedColArr, setUncheckedColArr] = useState({
    'building_number':[],
    'unit_number':[]
  });

  const updateFilterValue = (columnName, fieldValue, checked) => {
    let tempUncheckedColArr = {...uncheckedColArr};

    if(checked){
      tempUncheckedColArr[columnName].push(fieldValue)
      tempUncheckedColArr[columnName] = Array.from(new Set(tempUncheckedColArr[columnName]))
    } else{
      tempUncheckedColArr[columnName].splice(tempUncheckedColArr[columnName].indexOf(fieldValue),1);
    }

    setUncheckedColArr(tempUncheckedColArr)
  };

  const handleChange = (e) => {
    const fieldValue = e.target.value;
    const checked = !e.target.checked;
    const columnName = e.target.getAttribute("data-col-name");
    updateFilterValue(columnName, fieldValue, checked);
  };

  return (
    <div className="App">
      <input
        type="checkbox"
        defaultChecked={true}
        value="1"
        name={`checkbox[]`}
        data-col-name="building_number"
        onChange={handleChange}
      />
      <label>Building Number</label>

      <input
        type="checkbox"
        defaultChecked={true}
        value="123"
        name={`checkbox[]`}
        data-col-name="unit_number"
        onChange={handleChange}
      />
      <label>Unit Number 1</label>

      <input
        type="checkbox"
        defaultChecked={true}
        value="123"
        name={`checkbox[]`}
        data-col-name="unit_number"
        onChange={handleChange}
      />
      <label>Unit Number 2</label>
    </div>
  );
}

Hope it helps!

Related