0

I'm not sure if it's possible to do, in my React app, I have a <form> with the following input fields:

<TextField />
<TextField />
<TextField />

and I have a state

const [info, setInfo] = useState({
    firstName:"", 
    lastName:"",
    colors:[]
})

I know how to set a single field using ES6 Spread like setInfo(...info, firstName:e.target.value), but that doesn't seem to work with an array in Object.

Currently, if I want to set the colors, I go:

<TextField onChange={addColor1}/>
<TextField onChange={addColor2}/>
<TextField onChange={addColor3}/>

and then I create an array colors = [color1, color2, color 3], and lastly I `setInfo({...info, colors:colors})

But I want to know if there's a way to set the color array without having to write repeated functions like addColor1, addColor2 ...

Thank you!

3
  • Is there any specific reason why you want to do that ?? I'm just curious... To answer your question, you could use 'push' Commented Sep 11, 2021 at 13:44
  • Actually pushing to an array in state will mutate it. You can spread the array just as you are currently spreading the object. setInfo({...info, colors:[...info.colors, colorToAdd]}) Commented Sep 11, 2021 at 13:47
  • @NoxinDVictus say, in the future, the app grows, and people want to add more colors they like, then there should be a button to add more input field and allow people to input more colors, the solution in my code is never an ideal way I think Commented Sep 11, 2021 at 15:29

2 Answers 2

1

This is a very good question. Let's see if we can construct one.

  const addColor = color => e => {
    const oldColors = info.colors
    // do whatever to create a new colors
    // based on oldColors and color, ex.
    const colors = [...oldColors, color]
    
    setInfo({ ...info, colors: colors })
  }

You should be able to use it this way.

  <TextField onChange={addColor('red')} />

This is the idea, color => e is something i think you might find it useful. But i don't know exactly how you will pull off with an array structure. In the end i don't think your way would work, but just keep trying or search something called widget MultiSelect or Checkboxes or something. They are more used for an array of items.

Sign up to request clarification or add additional context in comments.

1 Comment

as i said, you need to see what's implemented in the TextField, maybe you don't need e, then you can drop it.
0

Yes, you can definitely use a single function to handle the change events for all form-controls.

It's better to change the colours' data structure to an object or a map but if you want to use an array here's an example:

Edit eloquent-pateu-lu2xo

export default function App() {
  const [info, setInfo] = useState({
    firstName: "",
    lastName: "",
    colors: new Array(3).fill("")
  });

  const handleChange = ({ target: { name, value } }) => {
    setInfo((prevInfo) => {
      if (name === "firstName" || name === "lastName") {
        return { ...prevInfo, [name]: value };
      }

      // to get 0/1/2 from color0/color1/color2
      const colorIndex = +name[name.length - 1];

      return {
        ...prevInfo,
        colors: Object.assign([...prevInfo.colors], { [colorIndex]: value })
      };
    });
  };

  return (
    <div className="App">
      <input
        type="text"
        value={info.firstName}
        name="firstName"
        onChange={handleChange}
      />
      <input
        type="text"
        value={info.lastName}
        name="lastName"
        onChange={handleChange}
      />
      <div>
        {info.colors.map((color, index) => {
          return (
            <textarea
              key={index}
              value={color}
              name={`color${index}`}
              onChange={handleChange}
            />
          );
        })}
      </div>
      {JSON.stringify(info)}
    </div>
  );
}

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.