React+ApexCharts时间线应用提交新任务后图表无法刷新问题求解
核心问题说明
- Form组件提交POST请求成功后没有触发数据重新拉取逻辑,原有按钮绑定的传值逻辑无效(Form自身无
series状态,传递的是无效值) - 现有
forEachTasks方法存在异步逻辑错误:setState是异步操作,刚执行完setState({tasks: result.tasks})就直接读取thisState.state.tasks无法拿到最新返回的服务端数据 - POST请求的回调逻辑写反:将错误处理写在了Promise成功回调的位置,成功插入数据后没有对应执行逻辑
1. 修正forEachTasks函数
const forEachTasks = (thisState) => { // 不需要外部传入newSeries,内部初始化即可 let newSeries = []; fetch("http://localhost:5600/api/task") .then(res => res.json()) .then( (result) => { thisState.setState({ isLoaded: true, tasks: result.tasks }); // 直接用接口返回的result.tasks遍历,不要读取state里的旧值 result.tasks.forEach((task) => { const dbTask = { x: task.taskname, y: [ new Date(task.begindate).getTime(), new Date(task.enddate).getTime() ] }; newSeries.push(dbTask); }); // 按照ApexCharts要求的格式更新series thisState.setState({ series: [{data: newSeries}] }); }, (error) => { thisState.setState({ isLoaded: true, error }); } ); } export default forEachTasks;
2. 修正ChartComponent组件
import React from 'react'; import Chart from "react-apexcharts"; import Form from "./Form"; import forEachTasks from './components_lib/forEachTasks'; class ChartComponent extends React.Component { constructor(props) { super(props); this.state = { tasks: [], error: null, isLoaded: false, series: [ { data: [ { x: '测试项', y: [ new Date('2021-11-01').getTime(), new Date('2021-12-01').getTime() ] } ] } ], options: { chart: { height: 350, type: 'rangeBar' }, plotOptions: { bar: { horizontal: true } }, xaxis: { type: 'datetime' }, legend: { show: false } } } } // 新增刷新图表方法,暴露给子组件调用 refreshChart = () => { forEachTasks(this); } componentDidMount() { // 初始化拉取数据 this.refreshChart(); } render () { return ( <div id="chart"> <Chart options={this.state.options} series={this.state.series} type="rangeBar" height={350} /> {/* 传递刷新方法给Form组件,不需要传递旧的series数据 */} <Form refreshChart={this.refreshChart} /> </div> ) } } export default ChartComponent;
3. 修正Form组件
import React from 'react'; import addNewTask from "./components_lib/addNewTask"; class Form extends React.Component { constructor(props) { super(props); this.state = { taskName: '', beginDate: '', endDate: '' } } handleTaskNameChange = (event) => { this.setState({ taskName: event.target.value }) } handleBeginDateChange = (event) => { this.setState({ beginDate: event.target.value }); } handleEndDateChange = (event) => { this.setState({ endDate: event.target.value }); } handleSubmit = (event) => { event.preventDefault(); addNewTask(this); fetch("http://localhost:5600/api/task", { method: 'POST', body: JSON.stringify({ taskname: this.state.taskName, begindate: this.state.beginDate, enddate: this.state.endDate, collaboratorId: 1 }), headers: {'Content-Type': 'application/json'} }) .then(res => res.json()) .then( // 补充成功回调,插入完成后调用父组件的刷新方法 (result) => { this.setState({ // 提交成功后清空表单 taskName: '', beginDate: '', endDate: '' }) this.props.refreshChart(); }, // 错误回调位置不变 (error) => { this.setState({ isLoaded: true, error }); } ); } render() { return ( <div> <form onSubmit={this.handleSubmit}> <label>任务名称</label> <input value={this.state.taskName} onChange={this.handleTaskNameChange}/> <label>开始日期</label> <input type="date" value={this.state.beginDate} onChange={this.handleBeginDateChange}/> <label>结束日期</label> <input type="date" value={this.state.endDate} onChange={this.handleEndDateChange}/> {/* 删除原有无效的onClick逻辑,提交逻辑统一在handleSubmit处理 */} <button type={'submit'}>Submit!</button> </form> </div> ); } } export default Form;
内容的提问来源于stack exchange,提问作者ikotamsl
相关产品推荐
相关产品推荐

