第三个下拉菜单基于前 2 个下拉菜单的选择,但第三个下拉菜单的状态总是落后 1 步
3rd dropdown is based off first 2 dropdown's selections but the 3rd's state is always 1 step behind
我有以下代码:
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>
在 homeSelect
和 hedgeSelect
被 selected 之后,'similarSymbols' 应该填充相应的数据。
问题是,'similarSymbols' 在 homeSelect
和 hedgeSelect
再次 select 之后才会正确填充,例如,select 一个下拉菜单和 select 另一个下拉菜单,然后再 select 其中一个。
好像状态落后了 1 步,我不知道如何让它工作。
感谢任何帮助,谢谢。
这是setState的async造成的,也是hook造成的
调用 exchange_change 时,状态尚未设置,并且选择了以前的值。
尝试使用 useEffect 来响应对 homeSelect
和 hedgeSelect
的更改:
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>
我有以下代码:
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>
在 homeSelect
和 hedgeSelect
被 selected 之后,'similarSymbols' 应该填充相应的数据。
问题是,'similarSymbols' 在 homeSelect
和 hedgeSelect
再次 select 之后才会正确填充,例如,select 一个下拉菜单和 select 另一个下拉菜单,然后再 select 其中一个。
好像状态落后了 1 步,我不知道如何让它工作。
感谢任何帮助,谢谢。
这是setState的async造成的,也是hook造成的
调用 exchange_change 时,状态尚未设置,并且选择了以前的值。
尝试使用 useEffect 来响应对 homeSelect
和 hedgeSelect
的更改:
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>