skip to Main Content

I have few inputs in component and each of them have onChange to change their value. How can i simplify this code so i don’t write x similar functions? If item will have 6 inputs so I will have to copy this functions 6 times and change only one word in it (item.x) which looks pointless but I cant figure out how to make it better.

onChange functions:

  const changeItemName = (event: any, id: string ) => {
    const newItems: any = [...items]
    const item: any = newItems.find((item:any) => item.id === id);
    item.name = event.target.value;
    setItems(newItems);
  }

  const changeItemDescription = (event: any, id: string ) => {
    const newItems: any = [...items]
    const item: any = newItems.find((item:any) => item.id === id);
    item.description = event.target.value;
    setItems(newItems);  
}

Inputs:

        <input 
          type='text' 
          name="name" 
          className='item-info-text' 
          placeholder='Nazwa przedmniotu' 
          maxLength={255} 
          value={item.name} 
          onChange={(e) => changeItemName(e, item.id)}
        />
        <input 
          type='text' 
          name="description" 
          className='item-info-text' 
          placeholder='Opis przedmniotu' 
          maxLength={255} 
          value={item.description} 
          onChange={(e) => changeItemDescription(e, item.id)}
        />

5

Answers


  1. Chosen as BEST ANSWER

    Solved it by adding [event.target.name] to item:

    item[event.target.name] = event.target.value;
    

  2. You can create a single function and n pass the name of the property you want to change as a parameter:

    const handleInputChange = (event: any, id: string, propertyName: string) => {
      const newItems: any = [...items]
      const item: any = newItems.find((item:any) => item.id === id);
      item[propertyName] = event.target.value;
      setItems(newItems);
    }
    
    Login or Signup to reply.
  3. You could create a dynamic onChange function that uses the input‘s name to set it’s value on a object where you keep all the input values

    const { useState } = React;
    
    const Example = () => {
    
        const onChange = (event) => {
            setValues({
                ...allValues,
                [event.target.name]: event.target.value
            });
        }
    
        const [allValues, setValues] = useState({
            name: '',
            description: ''
        });
    
        return (
            <div>
                <h1>{'Example'}</h1>
                <input 
                    type='text' 
                    name="name" 
                    className='item-info-text' 
                    placeholder='Nazwa przedmniotu' 
                    maxLength={255} 
                    value={allValues['name']} 
                    onChange={onChange}
                  />
                  <input 
                    type='text' 
                    name="description" 
                    className='item-info-text' 
                    placeholder='Opis przedmniotu' 
                    maxLength={255} 
                    value={allValues['description']} 
                    onChange={onChange}
                  />
            </div>
        )
    }
    ReactDOM.render(<Example />, document.getElementById("react"));
    <script src="https://cdnjs.cloudflare.com/ajax/libs/react/17.0.1/umd/react.production.min.js"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/17.0.1/umd/react-dom.production.min.js"></script>
    <div id="react"></div>
    Login or Signup to reply.
  4. I think you can simply create one onChange handler in which you can set the values dynamically

     const onChangeHandler=(event)=>{
        items[event.target.name] = event.target.value;
    }
    

    it will store all the fields value in the items array

    Login or Signup to reply.
  5. Witam!
    To simplify your code and avoid writing multiple similar functions for each input, you can create a single function that takes an additional parameter to determine which property of the item should be updated.
    i.e:

    const changeItemProperty = (event: any, id: string, property: string) => {
      const newItems: any = [...items];
      const item: any = newItems.find((item: any) => item.id === id);
      item[property] = event.target.value;
      setItems(newItems);
    };
    

    This function takes an additional property argument, which specifies which property of the item should be updated. You can now use this single function for both inputs by passing the respective property names:

    <input
      type="text"
      name="name"
      className="item-info-text"
      placeholder="Nazwa przedmniotu"
      maxLength={255}
      value={item.name}
      onChange={(e) => changeItemProperty(e, item.id, "name")}
    />
    <input
      type="text"
      name="description"
      className="item-info-text"
      placeholder="Opis przedmniotu"
      maxLength={255}
      value={item.description}
      onChange={(e) => changeItemProperty(e, item.id, "description")}
    />
    

    With this approach, you can easily handle multiple inputs with the same function by just passing the appropriate property name to the changeItemProperty function. This will make your code more concise and easier to maintain.

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search