0
votes

I am using react hooks useState to update an object. I have a reusable component, which is just an input, that I am passing props to and an onChange handler that updates the state.

How can i use the prop value "fooType" to dynamically update the state? This is working other than fooType in fooType: e.target.value` not being recognized as a variable. Is there a way to refactor for this to work in this manner?

The input component:

const Input = (props) => {
  const { foo, foos, setFoos, fooType } = props;

  return (
    <input type='text'
      placeholder={ foo }
      value={ foo }
      onChange={ (e) => setFoos({ ...foos, fooType: e.target.value }) } />
  );
};

Here is the file where I am passing the props to three inputs

const InputGroup = (props) => {
  // initial state
  const [foos, setFoos] = useState({
    foo1: 0, foo2: 0, foo3: 0
  });

  return (
    <div>
      <Input foo={ foos.foo1 }
        fooType='foo1'
        foos={ foos }
        setFoos={ setFoos } />

      <Input foo={ foos.foo2 }
        fooType='foo2'
        foos={ foos }
        setFoos={ setFoos } />

      <Input foo={ foos.foo3 }
        fooType='foo3'
        foos={ foos }
        setFoos={ setFoos }/>
    </div>
  );
}
3

3 Answers

1
votes

You are going to want to surround the fooType in [] to set a variable as key value.

onChange={ (e) => setFoos({ ...foos, [fooType] : e.target.value }) } />

As of the way you are writing it right now fooType is interpreted as a new key value. But the above change should fix it.

1
votes

Add brackets to your [fooType] to make it the object key

onChange={ (e) => setFoos({ ...foos, [fooType]: e.target.value }) }

Here a sandbox so you can play with it: https://codesandbox.io/s/exciting-ritchie-ijxxb

1
votes

you got your answer.. but i would suggest you better approach to this.

The input component:

const Input = props => {
  const { index, fields, setFields } = props;

  return (
    <input type='text'
      placeholder={ fields[index].placeHolder }
      value={ fields[index].value }
      onChange={ e => {
        let fieldsCopy = fields.slice()        // shallow copy
        fields[index].value = e.target.value
        setFields(fieldsCopy.slice())
      } } />
  );
};

and for your 3 component code -

const InputGroup = props => {
  // initial state
  const [fields, setFields] = useState([
    { value: 0, placeHolder: 'foo1' }
    { value: 0, placeHolder: 'foo2' }
    { value: 0, placeHolder: 'foo3' }
  ]);

  return (
    <div>
      {
        foos.map((element, index) => {
          <Input
            key={index}
            index={ index }
            fields={ fields }
            setFields={ setFields }
          />
        })
      }
    </div>
  );
}

ask if it's not clear