React如何将input选择的日期状态传入componentDidMount调用API避免死循环
问题解决方法
问题根源
componentDidMount执行时机是组件首次挂载完成,此时用户还未触发日期选择操作,dateState还保持初始值,自然拿不到用户选择的日期。- 直接在
componentDidUpdate中无判断触发请求+setState会导致无限循环:请求成功后setState会触发组件更新,再次进入componentDidUpdate又发起请求,无限重复。
实现步骤
- 统一
dateState的类型,后续存储的是格式化后的日期字符串,初始值不要设置为空数组,可设置为空字符串或者默认当天日期。 - 把API请求逻辑抽成独立公共方法,方便多处调用。
- 两种可选触发逻辑二选一即可:
- 方案A:在日期选择回调
dateHandler的setState异步回调中触发请求,无需使用componentDidUpdate - 方案B:在
componentDidUpdate中增加状态对比逻辑,仅当日期值发生变化时才发起请求,避免无限循环
- 方案A:在日期选择回调
import moment from 'moment'; import axios from 'axios'; import React from 'react'; export default class Med extends React.Component { constructor(props) { super(props); this.state = { // 可根据需求调整默认值,为空字符串则首次挂载不发起请求 dateState: moment().format("YYYY-MM-DD"), items: [] }; } // 抽离公共请求方法 fetchMedData = (date) => { const config = { headers: { Authorization: `token ${localStorage.getItem("token")}`, }, }; // 日期为空时不发起请求 if(!date) return; axios.get(`customer/medGET/?date=${date}`, config).then((res) => { this.setState({ items: res.data }); }); } dateHandler = (e) => { const date = moment(e.target.value).format("YYYY-MM-DD"); // 方案A:选完日期直接在setState回调触发请求,不需要用componentDidUpdate // this.setState({ dateState: date }, () => { // this.fetchMedData(this.state.dateState); // }); this.setState({ dateState: date }); }; componentDidMount() { // 组件挂载完成,用默认日期发起首次请求 this.fetchMedData(this.state.dateState); } // 方案B:仅当日期状态变化时触发请求 componentDidUpdate(prevProps, prevState) { if(prevState.dateState !== this.state.dateState) { this.fetchMedData(this.state.dateState); } } render() { return ( <table> <tr> <td> <input type="date" value={moment(this.state.dateState).format("YYYY-MM-DD")} onChange={this.dateHandler} /> </td> </tr> {/* 此处可自定义渲染items列表内容 */} </table> ); } }
内容的提问来源于stack exchange,提问作者user17427339
相关产品推荐
相关产品推荐

