Business
Jobs
  • About Us
  • Solutions
    • Job Postings
      Post your job and receive qualified candidates in 48h.
    • Candidate Assessments
      500+ technical and psychological tests, plus anti-fraud.
    • Headhunting
      Tailor-made executive search from start to finish.
    • Payroll + EOR
      Payroll dispersal and EOR across 15+ LATAM countries.
  • Pricing
  • Jobs

0

312
Views
remove value from form within component

I am trying to let users remove values from there current settings.

I have a series of values users can have for there settings that are displayed in a pill format that they can click X on to delete, i.e.,

export default function Pill({ value, handleChange }) {

  // const [times, setTimes] = useState([]);

    return (
      <div className="bg-gray-600 text-white text-xs px-2 py-0.5 w-max-content rounded-lg align-middle mr-1 mb-1">
        {value}
        <svg
          xmlns="http://www.w3.org/2000/svg"
          width="16"
          height="16"
          viewBox="0 0 24 24"
          fill="none"
          stroke="currentColor"
          strokeWidth="2"
          strokeLinecap="round"
          strokeLinejoin="round"
          className="inline-block align-middle cursor-pointer"
          onClick={() => handleChange(value, "remove")}
        >
          <line x1="18" y1="6" x2="6" y2="18" />
          <line x1="6" y1="6" x2="18" y2="18" />
        </svg>
      </div>
    );
  }

This is used as a component as below,

{substanceDetails &&
              substanceDetails.map((subst) => (
                <Pill
                  registerInput={register}
                  optionLabel="substance"
                  value={subst.substance}
                  key={subst.substance}
                  optionName="substance"
                  allOptions={["Dexamphetamine", "Ritalin"]}
                  handleChange={handleChange}
                />
              ))}

Given the handle change, which needs to be changed, but it would look something like this,

const handleChange = (value, mode) => {
    let updatedValues = values;
    if (mode === 'remove') {
      updatedValues = values.filter((elem) => elem !== value);
    } else if (!updatedValues.includes(value)) updatedValues = [...values, value];
    setValues(updatedvalues);
  };
over 4 years ago · Santiago Trujillo
2 answers
Answer question

0

Mutation issue

You are mutating state in your handleChange function:

const handleChange = (value, mode) => {
    let updatedValues = values; //takes the reference to state variable
    if (mode === 'remove') {
      updatedValues = values.filter((elem) => elem !== value); //mutation
    } else if (!updatedValues.includes(value)) updatedValues = [...values, value];
    setValues(updatedvalues);
  };

You can use something like this:

const handleChange = (value, mode) => {
    if(mode==="remove") setValues(vals => vals.includes(value) ? vals.filter(v => v !== value) : [...vals, value])
  };

If it is an array of objects:

.includes() won't work as expected if your array elements are not primitive values. You can use .find() or .some() in that case:

Example of filtering by the field duration for simplicity:

const handleChange = (value, mode) => {
    if(mode==="remove") setValues(vals => vals.find(v=> v.duration === value.duration) ? vals.filter(v => v.duration !== value.duration) : [...vals, value])
  };
over 4 years ago · Santiago Trujillo Report

0

After reading your code, I found the main problem might not be the mutation issue, but you didn't manage the state very well.

First, your substanceDetails should be stored in YourSubstanceListComponent component, not in your Pill component, something like this. This is the main reason why your first approach does not work.

// in YourSubstanceListComponent
const YourSubstanceListComponent = () = {
  const [values, setValues] = useState([]);
  const handleChange = (value, mode,optionName) => {
    // Should call `setValues` in this function
    const newValues = [];// TODO
    setValues(newValues);
  }

  return (
    <>
      {values.map(v => <Pill {...otherPillProps} value={v.substance} />)}
    </>
  )
}

Then, your handleChange should be placed in YourSubstanceListComponent. The reason why is you might don't want to pass setValues to your Pill component.

Next is the part about getting new removed values items. According the docs:

  • Array.find
  • Array.filter

They don't modify the original array. So you can use them like in your code and it should work.

But, I found some more problems in your code and I think you should check it again.

  • Array.reduce will return your array to a single value. I saw that you used it to get a new array from an array. It makes no sense since you can use map (when the number of elements does not change) or filter (when the number of elements will change). I rarely use any other methods apart from map and filter in all my life.
  • In your updated handleChange function, I don't see the optionName variable. Where does it come from? Maybe you didn't update your Pill component.
over 4 years ago · Santiago Trujillo Report
Answer question
Find remote jobs

Discover the new way to find a job!

Top jobs
Top job categories
Business
Post vacancy Pricing Sales
Legal
Terms and conditions Privacy policy
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Show me some job opportunities
There's an error!