0

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 Answers 3

1

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.

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

Comments

1

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

Comments

1

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

1 Comment

Nice! I accepted the other answer since it more directly answered the original question, but ended up refactoring using your exampe. I was originally trying to use a map but couldnt quite get it. Thanks a bunch.

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.