javascriptreactjsreact-hooksuse-state

How to set the value of inputs with ReactJS hooks?


I want to fill the inputs value of a form with default values once the modal is opened

I did it with pure javascript using document.getElementById(textId).value='some value as follow:

  for(var i=0; i<details_data.length;i++){
     let textId='text'+i;
     let amountId='amount'+i;
     document.getElementById(textId).value=details_data[i].text
  }

This worked fine. but I want to know how to do it with React since I don't believe this is a best practice.

what i tried is to set the input value like this:

<input name='text' id={textId} value={el.text} onChange={details_handler.bind(index)}/>

But this woudn't let me change the value of the input. it just set the default value, and when i type in the input the value woudn't change as I want.

This is my code

const [details_data,set_details_data]=useState([
    {'text':'','amount':''}
])
// called this function on `onChange` and store the data in `details_data`
function details_handler(e){
    let name=e.target.name;
    let value=e.target.value;
    details_data[this][name]=value;
    set_details_data(details_data);
  }

JSX:

(In my case user can add inputs as many as he wants,That's why I put the inputs in a the mapping loop)

  {
    details_data.map((el,index) => {
        let textId='text'+index;
        let amountId='amount'+index;
        return (
            <div key={index}>
                <input name='text' id={textId} value={el.text} onChange={details_handler.bind(index)}/>
                <input name='amount' id={amountId} onChange={details_handler.bind(index)}/>
            </div>
            );
      })
  }

Solution

  •  useEffect(() => {
         if(detailsProps) {
             set_details_data(detailsProps);
         }
     }, [detailsProps])
    

    where your detailsProps (data from the api) will look something like this

     detailsProps = [
        {'text':'text1','amount':'100'},
        {'text':'text2','amount':'200'}
     ]
    

    onChange Function

    const details_handler = (event, index) => {
       const items = [...details_data];
       items[index][event.target.name] = event.target.value;
       set_details_data(items);
    }
    

    your view

     {
    details_data.map((el,index) => {
        return (
            <div key={index}>
                <input name='text' value={el.text} onChange={(e) => details_handler(e, index)}/>
                <input name='amount' value={el.amount} onChange={(e) => details_handler(e, index)}/>
            </div>
            );
      })
    }