【问题标题】:3rd dropdown is based off first 2 dropdown's selections but the 3rd's state is always 1 step behind第三个下拉菜单基于前 2 个下拉菜单的选择,但第三个下拉菜单的状态始终落后 1 步
【发布时间】:2021-03-01 02:49:08
【问题描述】:

我有以下代码:

const [homeSelect, setHomeSelect] = useState('Home');
const [hedgeSelect, setHedgeSelect] = useState('Hedge');
const [symbolSelect, setSymbolSelect] = useState('');
const [similarSymbols, setSimilarSymbols] = useState([]);

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 = () => {
    setSimilarSymbols([]);
    //add symbols together from selected dropdowns
    var allSymbols = response.content.symbols[homeSelect] + response.content.symbols[hedgeSelect];
    console.log(allSymbols);

    //sort the symbols
    allSymbols = allSymbols.split(",");
    var sort_arr = allSymbols.sort();
    console.log(sort_arr);

    //find duplicates
    for(var i = 0; i < sort_arr.length-1; i++)
    {
      if(sort_arr[i + 1] == sort_arr[i]) { 
        setSimilarSymbols(similarSymbols => [...similarSymbols, sort_arr[i]]);
      }
    }
  }

<FormControl dense>
    <TextField
      id="standard-select-currency"
      select
      label="Home"
      className={classes.textField}
      value={homeSelect}
      onChange={handleHome}
      SelectProps={{
        native: true,
      }}
      helperText="Please select exchange"
    >
      <option>Home</option>
      {response ? response.content.exchanges.map((option) => (
        <option value={option}>
          {option}
        </option>
      )) : <option>Data is loading...</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"
    >
      <option>Hedge</option>
      {response ? response.content.exchanges.map((option) => (
        <option value={option}>
          {option}
        </option>
      )) : <option>Data is loading...</option>}
    </TextField>
  </FormControl>

  <FormControl dense>
    <TextField
      id="standard-select-currency"
      select
      label="Symbols"
      className={classes.textField}
      value={symbolSelect}
      onChange={handleSymbol}
      disabled={homeSelect == 'Home' || hedgeSelect == 'Hedge'}
      SelectProps={{
        native: true,
      }}
      helperText="Please select the exchanges"
    >
      <option>Symbol</option>
      {console.log(similarSymbols.map((element) => (element)))}
      {response ? similarSymbols.map((option) => (
        <option value={option}>
          {option}
        </option>
      )) : <option>Data is loading...</option>}
    </TextField>
  </FormControl>

选择homeSelecthedgeSelect 后,“similarSymbols”应填充相应的数据。

问题是,直到再次选择 homeSelecthedgeSelect 之后,“similarSymbols”才会正确填充,例如,选择一个下拉列表并选择另一个下拉列表,然后再选择其中一个.

状态似乎落后了 1 步,我不知道如何使它工作。

感谢您的帮助,谢谢。

【问题讨论】:

    标签: javascript reactjs use-state react-state


    【解决方案1】:

    这是由 setState 的异步引起的,也是钩子。

    到调用 exchange_change 时,状态尚未设置,并且选择了之前的值。

    尝试使用 useEffect 对 homeSelecthedgeSelect 的 chagnes 做出反应:

    const [homeSelect, setHomeSelect] = useState('Home');
    const [hedgeSelect, setHedgeSelect] = useState('Hedge');
    const [symbolSelect, setSymbolSelect] = useState('');
    const [similarSymbols, setSimilarSymbols] = useState([]);
    
    
    const handleHome = (event) => {
        setHomeSelect(event.target.value);
      };
    
    const handleHedge = (event) => {
        setHedgeSelect(event.target.value);
    };
    
    const handleSymbol = (event) => {
        setSymbolSelect(event.target.value);
    };
    React.useEffect(exchange_change, [homeSelect, hedgeSelect]) // Here you listen to changes and update similarSymbols once changes are made.
    
    const exchange_change = () => {
        setSimilarSymbols([]);
        //add symbols together from selected dropdowns
        var allSymbols = response.content.symbols[homeSelect] + response.content.symbols[hedgeSelect];
        console.log(allSymbols);
    
        //sort the symbols
        allSymbols = allSymbols.split(",");
        var sort_arr = allSymbols.sort();
        console.log(sort_arr);
    
        //find duplicates
        for(var i = 0; i < sort_arr.length-1; i++)
        {
          if(sort_arr[i + 1] == sort_arr[i]) { 
            setSimilarSymbols(similarSymbols => [...similarSymbols, sort_arr[i]]);
          }
        }
      }
    
    <FormControl dense>
        <TextField
          id="standard-select-currency"
          select
          label="Home"
          className={classes.textField}
          value={homeSelect}
          onChange={handleHome}
          SelectProps={{
            native: true,
          }}
          helperText="Please select exchange"
        >
          <option>Home</option>
          {response ? response.content.exchanges.map((option) => (
            <option value={option}>
              {option}
            </option>
          )) : <option>Data is loading...</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"
        >
          <option>Hedge</option>
          {response ? response.content.exchanges.map((option) => (
            <option value={option}>
              {option}
            </option>
          )) : <option>Data is loading...</option>}
        </TextField>
      </FormControl>
    
      <FormControl dense>
        <TextField
          id="standard-select-currency"
          select
          label="Symbols"
          className={classes.textField}
          value={symbolSelect}
          onChange={handleSymbol}
          disabled={homeSelect == 'Home' || hedgeSelect == 'Hedge'}
          SelectProps={{
            native: true,
          }}
          helperText="Please select the exchanges"
        >
          <option>Symbol</option>
          {console.log(similarSymbols.map((element) => (element)))}
          {response ? similarSymbols.map((option) => (
            <option value={option}>
              {option}
            </option>
          )) : <option>Data is loading...</option>}
        </TextField>
      </FormControl>
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2011-07-21
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-12-11
      • 2017-09-19
      • 1970-01-01
      相关资源
      最近更新 更多