I have a React DatePicker
component with an input element. In order to handle the onChange
event, I have onChangeHandler
function defined. However, when I want to define the types of all the functions passed down as parameters in the onChangeHandler
I get the following error:
Argument of type '(value: string) => void' is not assignable to parameter of type 'Dispatch<SetStateAction>'. Types of parameters 'value' and 'value' are incompatible.
Type 'SetStateAction' is not assignable to type 'string'. Type '(prevState: string) => string' is not assignable to type 'string'.ts(2345
This error disappears when I define the function as any, but of course we don't want any in the code :).
Below is my setup. I have an input component named Datepicker
in my main app that has gets a state from the main app.
const [value, setValue] = useState('');
It gets passed down as props in to a DatePicker
component as such:
return (
<form>
<label htmlFor='date-picker-input'>Date:</label>
<br />
**
<DatePicker
value={value}
setValue={setValue}
dateFormat='YYYY/MM/DD'
/>
**
<button
type='submit'
value='Submit'>
Submit
</button>
</form>
)
The DatePicker
component looks something like this:
import onChangeHandler from '../utility/onChangeHandler'
interface IDatePickerProps {
applicationMode?: boolean
value: string
setValue: (value: string) => void
dateFormat: DateFormat
}
const DatePicker: React.FC<IDatePickerProps> = (props) => {
const {value, setValue, dateFormat} = props
const applicationMode = props.applicationMode ? true : false
const [showCalendar, setShowCalendar] = useState(false)
const [errorMessage, setErrorMessage] = useState('')
const [clickedDate, setClickedDate] = useState<IClickedDate>({})
const [dateObject, setDateObject] = useState<IDateObject>({})
const [isClicked, setIsClicked] = useState<IIsClicked>({})
//bunch of functions
return (
<>
<div>
<label htmlFor='date-picker-input aria-label=`enter date in the following format`'>
{dateFormat}
</label>
<button>
<CalendarIcon />
</button>
<input
id='date-picker-input'
type='text'
value={value}
onChange={(e) =>
onChangeHandler(
e,
dateFormat,
setValue,
setErrorMessage,
setClickedDate,
setIsClicked
)
}
/>
</div>
<div>
<MonthPicker />
<table>
<DaysHeading />
<DatesOfMonth />
</table>
</div>
</>
)
}
Here is how the onChangeHandler
is defined and setValue
is used:
const onChangeHandler = (
event: React.ChangeEvent<HTMLInputElement>,
dateFormat: string,
//line causing the error is here:
setValue: React.Dispatch<React.SetStateAction<string>>,
setErrorMessage: React.Dispatch<React.SetStateAction<string>>,
setClickedDate: React.Dispatch<React.SetStateAction<IClickedDate>>,
setIsClicked: React.Dispatch<React.SetStateAction<IIsClicked>>
): void => {
const value = event.target.value
setValue(value)
let date = ''
let month = ''
let year = ''
let dateFormatCheck
let dateIsValid
let invalidAt
const errorNote = 'Please check entered '
if (value.length === 10) {
setErrorMessage('')
if (dateFormat === 'YYYY/MM/DD') {
dateFormatCheck = moment(value, 'YYYY/MM/DD', true)
dateIsValid = dateFormatCheck.isValid()
if (dateIsValid === true) {
//do some stuff
} else {
invalidAt = dateFormatCheck.invalidAt()
setErrorMessage(errorNote + errorDefinition(invalidAt))
}
}
}
}
//some other validators and no return value
export default onChangeHandler