在下拉列表中选择后 useState 未正确更新
useState is not properly updating after selections inside dropdowns
我有一个功能可以禁用下拉菜单,直到在其他 2 个下拉菜单中进行了选择。由于 useState
.
的一些异步问题,我认为它没有正确启用下拉菜单
const [homeSelect, setHomeSelect] = useState('Home');
const [hedgeSelect, setHedgeSelect] = useState('Hedge');
const [symbolSelect, setSymbolSelect] = useState('1');
const handleHome = (event) => {
setHomeSelect(event.target.value);
exchange_change();
};
const handleHedge = (event) => {
setHedgeSelect(event.target.value);
exchange_change();
};
const handleSymbol = (event) => {
setSymbolSelect(event.target.value);
};
const exchange_change = () => {
if (homeSelect != 'Home' && hedgeSelect != 'Hedge'){
//enable the symbol dropdown
setDisabled(false);
} else {
//disable the select exchanges dropdown
setDisabled(true);
}
}
<FormControl dense>
<TextField
id="standard-select-currency"
select
label="Home"
className={classes.textField}
value={homeSelect}
onChange={handleHome}
SelectProps={{
native: true,
}}
helperText="Please select exchange"
>
{home.map((option) => (
<option key={option.value} value={option.value}>
{option.label}
</option>
))}
</TextField>
</FormControl>
<FormControl dense>
<TextField
id="standard-select-currency"
select
label="Hedge"
className={classes.textField}
value={hedgeSelect}
onChange={handleHedge}
SelectProps={{
native: true,
}}
helperText="Please select exchange"
>
{hedge.map((option) => (
<option key={option.value} value={option.value}>
{option.label}
</option>
))}
</TextField>
</FormControl>
<FormControl dense>
<TextField
id="standard-select-currency"
select
label="Symbols"
className={classes.textField}
value={symbolSelect}
onChange={handleSymbol}
disabled={disabled}
SelectProps={{
native: true,
}}
helperText="Please select the exchanges"
>
{symbols.map((option) => (
<option key={option.value} value={option.value}>
{option.label}
</option>
))}
</TextField>
</FormControl>
home
和 hedge
下拉菜单需要在启用 symbol
下拉菜单之前进行选择。错误是 symbol
下拉菜单只有在多次选择 home
和 hedge
之后才会启用。
如何更改我正在使用的方法以使用 useReducer
(如果这将解决状态更新问题)?我试着阅读它,但不明白我的 switch case 是什么。
感谢任何帮助,谢谢。
“设置”操作是异步的。所以当你这样做时:
setHomeSelect(event.target.value);
exchange_change();
在调用第二个方法调用时,变量 homeSelect
已 未更改 。当逻辑完成处理并且组件准备 re-render.
时,它将发生变化
更重要的是,这不是很React-like:
const exchange_change = () => {
if (homeSelect != 'Home' && hedgeSelect != 'Hedge'){
//enable the symbol dropdown
setDisabled(false);
} else {
//disable the select exchanges dropdown
setDisabled(true);
}
}
虽然您在此处修改状态值,但从概念上讲,您似乎是在尝试修改 UI。不。 UI 组件可以只响应状态。因此,您可以在“符号”组件中执行此操作来代替该方法:
disabled={homeSelect == 'Home' || hedgeSelect == 'Hedge'}
如果您想将其放入方法中,请将其放入由组件调用的方法中,而不是在 re-render 之前调用的方法中。例如:
disabled={() => checkSelects()}
那个方法可以是:
const checkSelects = () =>
homeSelect == 'Home' || hedgeSelect == 'Hedge';
但总体而言,请注意此处的操作顺序。执行 UI 事件调用的所有逻辑,这些逻辑将更新排队到状态。然后状态得到更新。然后组件 re-render (如果需要)。不要依赖于该逻辑期间正在更新的状态。
我有一个功能可以禁用下拉菜单,直到在其他 2 个下拉菜单中进行了选择。由于 useState
.
const [homeSelect, setHomeSelect] = useState('Home');
const [hedgeSelect, setHedgeSelect] = useState('Hedge');
const [symbolSelect, setSymbolSelect] = useState('1');
const handleHome = (event) => {
setHomeSelect(event.target.value);
exchange_change();
};
const handleHedge = (event) => {
setHedgeSelect(event.target.value);
exchange_change();
};
const handleSymbol = (event) => {
setSymbolSelect(event.target.value);
};
const exchange_change = () => {
if (homeSelect != 'Home' && hedgeSelect != 'Hedge'){
//enable the symbol dropdown
setDisabled(false);
} else {
//disable the select exchanges dropdown
setDisabled(true);
}
}
<FormControl dense>
<TextField
id="standard-select-currency"
select
label="Home"
className={classes.textField}
value={homeSelect}
onChange={handleHome}
SelectProps={{
native: true,
}}
helperText="Please select exchange"
>
{home.map((option) => (
<option key={option.value} value={option.value}>
{option.label}
</option>
))}
</TextField>
</FormControl>
<FormControl dense>
<TextField
id="standard-select-currency"
select
label="Hedge"
className={classes.textField}
value={hedgeSelect}
onChange={handleHedge}
SelectProps={{
native: true,
}}
helperText="Please select exchange"
>
{hedge.map((option) => (
<option key={option.value} value={option.value}>
{option.label}
</option>
))}
</TextField>
</FormControl>
<FormControl dense>
<TextField
id="standard-select-currency"
select
label="Symbols"
className={classes.textField}
value={symbolSelect}
onChange={handleSymbol}
disabled={disabled}
SelectProps={{
native: true,
}}
helperText="Please select the exchanges"
>
{symbols.map((option) => (
<option key={option.value} value={option.value}>
{option.label}
</option>
))}
</TextField>
</FormControl>
home
和 hedge
下拉菜单需要在启用 symbol
下拉菜单之前进行选择。错误是 symbol
下拉菜单只有在多次选择 home
和 hedge
之后才会启用。
如何更改我正在使用的方法以使用 useReducer
(如果这将解决状态更新问题)?我试着阅读它,但不明白我的 switch case 是什么。
感谢任何帮助,谢谢。
“设置”操作是异步的。所以当你这样做时:
setHomeSelect(event.target.value);
exchange_change();
在调用第二个方法调用时,变量 homeSelect
已 未更改 。当逻辑完成处理并且组件准备 re-render.
更重要的是,这不是很React-like:
const exchange_change = () => {
if (homeSelect != 'Home' && hedgeSelect != 'Hedge'){
//enable the symbol dropdown
setDisabled(false);
} else {
//disable the select exchanges dropdown
setDisabled(true);
}
}
虽然您在此处修改状态值,但从概念上讲,您似乎是在尝试修改 UI。不。 UI 组件可以只响应状态。因此,您可以在“符号”组件中执行此操作来代替该方法:
disabled={homeSelect == 'Home' || hedgeSelect == 'Hedge'}
如果您想将其放入方法中,请将其放入由组件调用的方法中,而不是在 re-render 之前调用的方法中。例如:
disabled={() => checkSelects()}
那个方法可以是:
const checkSelects = () =>
homeSelect == 'Home' || hedgeSelect == 'Hedge';
但总体而言,请注意此处的操作顺序。执行 UI 事件调用的所有逻辑,这些逻辑将更新排队到状态。然后状态得到更新。然后组件 re-render (如果需要)。不要依赖于该逻辑期间正在更新的状态。