Reputation: 2870
I'm trying to migrate legacy code-base from class-based to function based using hooks.
The legacy code was like :
constructor(props){
super(props)
this.state = {
pickerProps: {
onPickDate: this.onPickDate,
activeColor: "#119955",
date: "12-12-2012"
},
inputStyle: "",
selectedDate: null
}
}
onPickDate = date => {
this.setState((state) => ({
selectedDate: date
}))
}
onInputChange = (prop, value) => {
this.setState((state) => ({
pickerProps: {
...state.pickerProps,
[prop]: value
}
}))
}
changeInputStyle = e => {
const value = e.target.value
this.setState((state) => ({inputStyle: value}))
}
and the new code is :
const [inputStyle, setInputStyle] = useState("");
const [selectedDate, setSelectedDate] = useState(null);
const [pickerProps, setPickerProps] = useState({
onPickDate:onPickDate, // How to pass function here
activeColor: "#119955",
date: "12-12-2012",
});
// This is the function I want to pass to useState()
const onPickDate = (date) => {
setSelectedDate(date);
};
const onInputChange = (prop, value) => {
setPickerProps({ [prop]: value });
};
const changeInputStyle = (e) => {
const value = e.target.value;
setInputStyle(value);
};
I receive a warning : The onPickDate was used before defined
Also when I send pickerProps
to DatePicker
:
<div className="date-picker">
<DatePicker {...pickerProps} />
</div>
It invokes an error :
OnPickDate is not defined ()
Upvotes: 1
Views: 728
Reputation: 281676
The problem here is related to function hoisting. The function you have declared is of type const and such variables with const or let declaration are not hoisted.
If you declare the function with function definition
it will work without having to write it above useState
const [inputStyle, setInputStyle] = useState("");
const [selectedDate, setSelectedDate] = useState(null);
const [pickerProps, setPickerProps] = useState({
onPickDate:onPickDate, // How to pass function here
activeColor: "#119955",
date: "12-12-2012",
});
function onPickDate(date) {
setSelectedDate(date);
};
const onInputChange = (prop, value) => {
setPickerProps({ [prop]: value });
};
const changeInputStyle = (e) => {
const value = e.target.value;
setInputStyle(value);
};
However you need to store functions in state as it will make it difficult for you to update state, you can directly pass them as props to children
const [inputStyle, setInputStyle] = useState("");
const [selectedDate, setSelectedDate] = useState(null);
const [pickerProps, setPickerProps] = useState({
activeColor: "#119955",
date: "12-12-2012",
});
// This is the function I want to pass to useState()
const onPickDate = (date) => {
setSelectedDate(date);
};
const onInputChange = (prop, value) => {
setPickerProps({ [prop]: value });
};
const changeInputStyle = (e) => {
const value = e.target.value;
setInputStyle(value);
};
return (
<div className="date-picker">
<DatePicker {...pickerProps} onPickDate ={onPickDate}/>
</div>
}
Upvotes: 2