How to call event onChange in a input when i click a button and update de value of input React

I trying to create a component with input type number, but i have a problem when my value change, the event onChange that input is not called, how i can fix this? because i have to pass the new value to the father component. My code

//My Component
import React, { useState } from 'react';
import { AddCircle, RemoveCircle } from '@material-ui/icons'

import './inputnumber.css'
function InputNumber({ defaultValue, onClick, value, onInputChange }) {
    const [Value, setVal] = useState(value|| 1)
    function updateValue(value){
        setVal(value)
        return onInputChange(value)
    }
    function  IncrementValue(){
        setVal(Value + 1)
     
    }
    function DecrementValue(){
        setVal(Value - 1)
    }
    return (
        <div className='inputNumber-Container'>
            <AddCircle onClick = {() => IncrementValue()}  className='input-number-button'></AddCircle>
            <input type='number' value = {Value} id = 'inputvalue'  onChange = {(e) => updateValue(e.target.value)} ></input>
            <RemoveCircle onClick = {() => DecrementValue()} className='input-number-button'></RemoveCircle>
        </div>
    )
}

export default InputNumber;

When i use the input and change the value manually its works, but when i try to use the buttons, my value update normaly but the event onChange don’t pass to the father component the value updated.

Answer

You have both a local Value and a value from props. Your code right now doesn’t work because you are not calling onInputChange to update the parent state from your IncrementValue and DecrementValue handlers. You only call onInputChange from the updateValue handler on the input onChange event.

It is not a good idea to duplicate props in state because it leads to out-of-sync values like this. You should remove the local value state and just rely on the parent’s value. This is what we call a “controlled component” because it doesn’t manage any state of its own.

Instead of calling setVal in your increment and decrement handlers you should call onInputChange to update the parent state.

function InputNumber({ defaultValue = 1, value, onInputChange }) {
  function updateValue(value) {
    onInputChange(value);
  }
  function IncrementValue() {
    onInputChange(value + 1);
  }
  function DecrementValue() {
    onInputChange(value - 1);
  }
  return (
    <div className="inputNumber-Container">
      <AddCircle
        onClick={() => IncrementValue()}
        className="input-number-button"
      />
      <input
        type="number"
        value={value ?? defaultValue}
        id="inputvalue"
        onChange={(e) => updateValue(e.target.value)}
      />
      <RemoveCircle
        onClick={() => DecrementValue()}
        className="input-number-button"
      />
    </div>
  );
}

Of course those handlers are simple enough that you can just write them inline.

function InputNumber({ defaultValue = 1, value, onInputChange }) {
  return (
    <div className="inputNumber-Container">
      <AddCircle
        onClick={() => onInputChange(value + 1)}
        className="input-number-button"
      />
      <input
        type="number"
        value={value ?? defaultValue}
        id="inputvalue"
        onChange={(e) => onInputChange(e.target.value)}
      />
      <RemoveCircle
        onClick={() =>  onInputChange(value - 1)}
        className="input-number-button"
      />
    </div>
  );
}