【问题标题】:useState is not properly updating after selections inside dropdowns在下拉列表中进行选择后,useState 未正确更新
【发布时间】:2020-11-03 19:51:27
【问题描述】:

我有一个功能可以禁用下拉菜单,直到在其他 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>

homehedge 下拉菜单需要在启用 symbol 下拉菜单之前进行选择。错误是symbol 下拉菜单在homehedge 被多次选择后才会启用。

如何更改我使用的方法以使用 useReducer 代替(如果这将解决状态更新问题)?我尝试阅读它,但不明白我的开关盒是什么。

感谢您的帮助,谢谢。

【问题讨论】:

    标签: javascript reactjs react-hooks use-state use-reducer


    【解决方案1】:

    “设置”操作是异步的。所以当你这样做时:

    setHomeSelect(event.target.value);
    exchange_change();
    

    当调用第二个方法调用时,变量homeSelect 没有改变。当逻辑完成处理并且组件准备重新渲染时,它将发生变化。

    更重要的是,这不是很像 React:

    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'}
    

    如果您想将其放入方法中,请将其放入由组件调用的方法中,而不是在重新渲染之前调用。例如:

    disabled={() => checkSelects()}
    

    而那个方法可以是:

    const checkSelects = () => 
      homeSelect == 'Home' || hedgeSelect == 'Hedge';
    

    但总的来说,请注意这里的操作顺序。由 UI 事件调用的所有逻辑都会执行,这会将更新排队到状态。然后状态得到更新。然后组件重新渲染(如有必要)。不要依赖在该逻辑期间更新的状态。

    【讨论】:

    • 有道理,但太奇怪了。为什么 React 会通读 setHomeSelect(event.target.value); exchange_change(); 并等到函数完成才能更改状态?开发人员似乎更加困惑
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-03-20
    • 2019-07-08
    • 1970-01-01
    • 1970-01-01
    • 2011-12-02
    相关资源
    最近更新 更多