React Autosuggest组件onSelect获取旧值问题求助
问题:AWS Cloudscape Autosuggest组件onSelect事件无法获取最新状态值
我基于AWS Cloudscape实现了自动补全搜索输入框,在使用onSelect事件保存React状态时,遇到了状态更新延迟的问题:选择第二个选项后,才会显示第一个选项的内容。推测是state异步更新导致的,请问如何获取最新的选择值?
import React from "react"; import Regions from "./trailforks_regions.json" import RegionNames from "./region_names.json" import * as dfd from "danfojs"; import { Autosuggest } from '@cloudscape-design/components'; export class AutoCompleteInputComponent extends React.Component { constructor(props) { super(props); this.state = { df: new dfd.DataFrame(Regions), value: null, final_value: "", options: [], status: "loading", regionContext: [], uri_value: "", loaded: false }; } lookupRegionUriName() { console.log("Checking for uri region name on:" + this.state.final_value) let region_name_split = this.state.final_value.split(",")[0] let query_df = this.state.df.query(this.state.df["name"].eq(region_name_split)) let uri_name = query_df["region_uri_name"].values console.log("found:" + uri_name) return uri_name } handleChange = event => { this.setState({ value: event.detail.value }); }; handleSelect = event => { console.log(event) // 这里能打印正确数据!但state没更新成这个值 this.setState({ final_value: event.detail.value }); this.lookupRegionUriName(this.state.final_value) }; handleLoadItems = ({ detail: { filteringText, firstPage, samePage } }) => { this.filteringText = filteringText; var my_options = RegionNames.filter(regions => regions.toLowerCase().startsWith(this.filteringText.toLowerCase())) var region_values = [] for (var i = 0; i <= my_options.length; i++) { region_values.push({ value: my_options[i] }) } this.setState({ options: region_values.slice(0, 25), status: 'loading', }); }; enteredTextLabel = value => `Use: "${value}"`; renderInput() { if (this.state.df != null) { const { status, value, options, final_value, uri_value } = this.state; return ( <> <Autosuggest onChange={this.handleChange} onSelect={this.handleSelect} onLoadItems={this.handleLoadItems} value={value} options={options} enteredTextLabel={this.enteredTextLabel} ariaLabel="Autosuggest example with suggestions" placeholder="Enter Trailforks Region Name" empty="No matches found" finishedText={this.filteringText ? `End of "${this.filteringText}" results` : 'End of all results'} //status={status} loadingText="searching" filteringType="manual" /> </> ) } else { return (<></>) } } render() { return ( <> {this.renderInput()} </> ) } }
解决方案
问题确实出在React状态更新的异步性上。setState是异步操作,调用后不会立即更新state,所以你在handleSelect里调用lookupRegionUriName时,this.state.final_value还是更新前的旧值。
你可以通过两种方式解决:
1. 直接使用事件中的最新值
既然event.detail.value已经是选中的最新值,直接把它传递给lookupRegionUriName即可,不需要依赖state:
handleSelect = event => { const selectedValue = event.detail.value; console.log(selectedValue); this.setState({ final_value: selectedValue }); this.lookupRegionUriName(selectedValue); // 直接传最新值 }; // 同时修改lookupRegionUriName方法,接收参数 lookupRegionUriName(selectedValue) { console.log("Checking for uri region name on:" + selectedValue) let region_name_split = selectedValue.split(",")[0] let query_df = this.state.df.query(this.state.df["name"].eq(region_name_split)) let uri_name = query_df["region_uri_name"].values console.log("found:" + uri_name) return uri_name }
2. 使用setState的回调函数
如果后续逻辑必须依赖更新后的state,可以利用setState的第二个参数(回调函数),它会在state更新完成后执行:
handleSelect = event => { const selectedValue = event.detail.value; console.log(selectedValue); this.setState({ final_value: selectedValue }, () => { // 这里的state已经是更新后的 this.lookupRegionUriName(); }); };
这两种方式都能确保你获取到最新的选中值,避免异步更新导致的延迟问题。
内容的提问来源于stack exchange,提问作者Joshua Faust
相关产品推荐
相关产品推荐

