React-Hook-Form 控制器忽略 useEffect
React-Hook-Form Controller ignoring useEffect
我有两个组件,其中 selectBirthMonth 取决于 SelectBirthYear。这就是我使用 useEffect 来观察 selectedYear 变化的原因,这样我就可以在需要时更改 selectedMonth。
所以在控制器上下文中,我的组件如下所示
<Controller
control={control}
name="selectedBirthYear"
defaultValue={years[0]}
render={({ field }) => (
<SelectBirthYear
field={field}
years={years}
value={selectedYear}
defaultValue={selectedYear}
onChange={useEffect(() => {setSelectedYear(field.value)})}
/>
)}
/>
</div>
和...
<Controller
control={control}
name="selectedBirthMonth"
defaultValue={months[0]}
render={({ field }) => (
<SelectBirthMonth
field={field}
startYear={startYear}
selectedYear={selectedYear}
months={months}
value={selectedMonth}
defaultValue={selectedMonth}
reducedMonths={reducedMonths}
onChange={useEffect(() => setSelectedMonth(field.value))}
/>
)}
/>
SelectBirthMonth 完全忽略了以下代码:
const [selectedMonth, setSelectedMonth] = useState(months[0]);
const watchYearChange = () => {
if(Number(selectedYear.name) == startYear){
setSelectedMonth(reducedMonths[reducedMonths.length - 1]);
}
};
useEffect(() => watchYearChange(), [selectedYear]);
意思是,无论选择哪一年,月份都不会反应。我想念什么?
我建议使用像 date-fns
这样的小型日期库来处理与日期相关的事情。这是一个很棒的包,这里是 docs。如果将来需要,它也可以为您处理 i18n。
我在下面的 CodeSandbox 中使用了它,还纠正了一些问题:
- 当您使用 RHF 时,您不需要为您的组件设置额外的状态,因为 RHF 会为您管理表单状态。
- 如果你只用一个日期来表示整个生日,那就简单多了——这样你将始终拥有年、月、日的当前值,而不需要观察值或使用额外定义的状态
答案太简单了,无法工作,但确实如此。好几次我都在 post 和 上阅读这个 ,但无法真正理解我在哪里以及如何使用 setValue。正如我假设的那样,我的 select 的值并没有改变,即使我正在观察兄弟状态的变化。
所以我将 setValue 放入 useEffect 钩子中,其余保持不变:
const monthSelect = (data) => {
setSelectedMonth(months[data.id - 1]);
};
const watchYearChange = () => {
if(Number(selectedYear.name) == startYear){
setSelectedMonth(lastAvaliableMonth)
}
};
useEffect(() => setValue('selectedBirthMonth', lastAvaliableMonth), [selectedYear]);
为了以防万一,这里有两个兄弟姐妹:
<Controller
control={control}
name="selectedBirthYear"
defaultValue={years[0]}
render={({ field }) => (
<SelectBirthYear
field={field}
years={years}
value={selectedYear}
defaultValue={selectedYear}
onChange={useEffect(() => {setSelectedYear(field.value)})}
/>
)}
/>
...和
<Controller
control={control}
name="selectedBirthMonth"
defaultValue={selectedMonth}
render={({ field }) => (
< SelectBirthMonth
field={field}
startYear={startYear}
selectedYear={selectedYear}
months={months}
value={selectedMonth}
reducedMonths={reducedMonths}
onChange={useEffect(() => monthSelect(field.value)), [selectedMonth]}/>
)}
/>
如果这个解决方案不太好,请在评论中告诉我。我完全是初学者。
我有两个组件,其中 selectBirthMonth 取决于 SelectBirthYear。这就是我使用 useEffect 来观察 selectedYear 变化的原因,这样我就可以在需要时更改 selectedMonth。
所以在控制器上下文中,我的组件如下所示
<Controller
control={control}
name="selectedBirthYear"
defaultValue={years[0]}
render={({ field }) => (
<SelectBirthYear
field={field}
years={years}
value={selectedYear}
defaultValue={selectedYear}
onChange={useEffect(() => {setSelectedYear(field.value)})}
/>
)}
/>
</div>
和...
<Controller
control={control}
name="selectedBirthMonth"
defaultValue={months[0]}
render={({ field }) => (
<SelectBirthMonth
field={field}
startYear={startYear}
selectedYear={selectedYear}
months={months}
value={selectedMonth}
defaultValue={selectedMonth}
reducedMonths={reducedMonths}
onChange={useEffect(() => setSelectedMonth(field.value))}
/>
)}
/>
SelectBirthMonth 完全忽略了以下代码:
const [selectedMonth, setSelectedMonth] = useState(months[0]);
const watchYearChange = () => {
if(Number(selectedYear.name) == startYear){
setSelectedMonth(reducedMonths[reducedMonths.length - 1]);
}
};
useEffect(() => watchYearChange(), [selectedYear]);
意思是,无论选择哪一年,月份都不会反应。我想念什么?
我建议使用像 date-fns
这样的小型日期库来处理与日期相关的事情。这是一个很棒的包,这里是 docs。如果将来需要,它也可以为您处理 i18n。
我在下面的 CodeSandbox 中使用了它,还纠正了一些问题:
- 当您使用 RHF 时,您不需要为您的组件设置额外的状态,因为 RHF 会为您管理表单状态。
- 如果你只用一个日期来表示整个生日,那就简单多了——这样你将始终拥有年、月、日的当前值,而不需要观察值或使用额外定义的状态
答案太简单了,无法工作,但确实如此。好几次我都在 post 和
所以我将 setValue 放入 useEffect 钩子中,其余保持不变:
const monthSelect = (data) => {
setSelectedMonth(months[data.id - 1]);
};
const watchYearChange = () => {
if(Number(selectedYear.name) == startYear){
setSelectedMonth(lastAvaliableMonth)
}
};
useEffect(() => setValue('selectedBirthMonth', lastAvaliableMonth), [selectedYear]);
为了以防万一,这里有两个兄弟姐妹:
<Controller
control={control}
name="selectedBirthYear"
defaultValue={years[0]}
render={({ field }) => (
<SelectBirthYear
field={field}
years={years}
value={selectedYear}
defaultValue={selectedYear}
onChange={useEffect(() => {setSelectedYear(field.value)})}
/>
)}
/>
...和
<Controller
control={control}
name="selectedBirthMonth"
defaultValue={selectedMonth}
render={({ field }) => (
< SelectBirthMonth
field={field}
startYear={startYear}
selectedYear={selectedYear}
months={months}
value={selectedMonth}
reducedMonths={reducedMonths}
onChange={useEffect(() => monthSelect(field.value)), [selectedMonth]}/>
)}
/>
如果这个解决方案不太好,请在评论中告诉我。我完全是初学者。