React Class Component中如何获取input值并更新state发起axios请求
问题根因
- 输入框未绑定
value属性,属于非受控组件:即使你通过setState更新了price的值,输入框也不会同步显示最新状态,视觉上会误以为setState没有生效。 - 请求逻辑仅在
componentDidMount生命周期执行一次:输入价格点击提交后没有触发新的接口请求,列表数据不会更新。 - 未阻止表单默认提交行为:点击提交按钮会触发浏览器原生表单提交,导致页面刷新,所有组件状态丢失。
最佳实践方案
- 将接口请求逻辑封装为独立的可复用方法,初始化、提交场景都可以直接调用,避免重复代码。
- 输入框改为受控组件,双向绑定
this.state.price,保证状态和视图一致。 - 新增表单提交事件处理,阻止默认刷新行为后触发新的请求。
修复后完整代码
interface RouteParam { price: any; } interface CouponByPrice extends RouteComponentProps<RouteParam> { } interface CouponDetailState { coupons: CouponModel[]; price: string; } class GetCouponByPrice extends Component<CouponByPrice, CouponDetailState> { public constructor(props: CouponByPrice) { super(props); this.state = { coupons: null, price: '150' }; } // 封装请求逻辑,可复用 private async fetchCoupons(price: string) { try { const response = await axios({ method: 'get', url: globals.urls.customerCouponsByPrice, params: { price }, }) store.dispatch(couponsAction(response.data)); this.setState({ coupons: response.data }); } catch (err) { notify.error(err); } } public async componentDidMount() { // 初始化调用 await this.fetchCoupons(this.state.price); } textHandler = (event: React.ChangeEvent<HTMLInputElement>) => { this.setState({price: event.target.value}) } // 表单提交处理 submitHandler = (event: React.FormEvent<HTMLFormElement>) => { // 阻止默认表单提交刷新页面 event.preventDefault(); // 用最新的price发起请求 this.fetchCoupons(this.state.price); } public render(): JSX.Element { return ( <div className="CatDetails Box"> {!this.state.coupons && <EmptyView msg="No Coupons for that price" />} {this.state.coupons && ( <> <div className="top"> <h1>Coupon By Maximum price</h1> </div> {/* 绑定提交事件 */} <form onSubmit={this.submitHandler}> <label> Add Price: {/* 新增value绑定,变为受控组件 */} <input onChange={this.textHandler} value={this.state.price} type="number" name="price" /> </label> <input type="submit" value="Submit" /> </form> <div className="card"> <Box m={4} pt={4} > <Grid container spacing={6} direction="row" justifyContent="space-evenly" alignItems="center" style={{ minHeight: '80vh' }} > { this.state.coupons.map(c => ( <Grid item xs={6} sm={4} > <Card2 key={c.id} coupon={c} /> </Grid> )) } </Grid> </Box> </div> <br /> <br /> <NavLink to="/home">Back</NavLink> </> )} </div> ); } } export default GetCouponByPrice;
额外注意事项
setState是异步操作,如果需要在状态更新完成后立刻执行逻辑,可以使用第二个回调参数:this.setState({price: '200'}, () => { 这里可以拿到更新后的this.state.price })- 类组件表单场景优先使用受控组件写法,所有输入状态统一维护在
state中,避免视图和状态不同步的问题。
内容的提问来源于stack exchange,提问作者Fastaca Girasol
相关产品推荐
相关产品推荐

