首页 > 解决方案 > 提交新任务后刷新图表

问题描述

我正在使用 ApexCharts 和 React 为时间线制作客户端服务器应用程序。(https://github.com/ikotamsl/timeline-project.git

将新任务插入数据库后,我很难刷新图表组件。这个想法很简单:当我点击“提交”按钮时,表单中的新任务被插入到数据库中,然后一个新的 GET 被发送到服务器,从数据库获取更新的信息。

我知道我想让应用程序做什么,我只是没有足够的知识在我的代码中实现它

表单组件:

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(

                // Примечание: важно обрабатывать ошибки именно здесь, а не в блоке catch(),
                // чтобы не перехватывать исключения из ошибок в самих компонентах.
                (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}/>
                    <button type={'submit'} onClick={() => {this.props.updateChartFromForm(this.state.series)}}>Submit!</button>
                </form>
            </div>
        );
    }
}

export default Form;

图表组件:


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,
            taskName: '',
            beginDate: '',
            endDate: '',
            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
                }
            }
        }
    }


    updateChartFromForm = async (data) => {
        this.setState({
            series: data
        });
    }

    componentDidMount() {

        let newSeries = [];

        forEachTasks(newSeries, this);
    }

    render () {
        return (
            <div id="chart">
                <Chart options={this.state.options} series={this.state.series} type="rangeBar" height={350} />
                <Form updateChartFromForm={this.updateChartFromForm} series={this.state.series} />
            </div>
        )
    }
}
export default ChartComponent;

forEachTasks 函数(用于从 db 获取任务)

const forEachTasks = (newSeries, thisState) => {

    fetch("http://localhost:5600/api/task")
        .then(res => res.json())
        .then(
            (result) => {
                thisState.setState({
                    isLoaded: true,
                    tasks: result.tasks
                });


                // Каждое полученное с сервера задание
                // преобразуем в нужный для апекса формат
                // и пушим в массив данных

                // По всей видимости, массив tasks будет в нужном нам виде только во время выполнения fetch,
                // иначе я не могу объяснить, почему после выхода отсюда мы не можем также проитеррировать
                // this.state.tasks и заполнить this.state.series нужными нам данными. Загадка..............

                thisState.state.tasks.forEach((task) => {

                    const dbTask = {
                        data: [
                            {
                                x: task.taskname,
                                y: [
                                    new Date(task.begindate).getTime(),
                                    new Date(task.enddate).getTime()
                                ]
                            }
                        ]
                    }
                    newSeries.push(dbTask);
                });

                // Обновляем массив данных диаграммы данными из БД

                thisState.setState({
                    series: newSeries
                });

            },
            // Примечание: важно обрабатывать ошибки именно здесь, а не в блоке catch(),
            // чтобы не перехватывать исключения из ошибок в самих компонентах.
            (error) => {
                thisState.setState({
                    isLoaded: true,
                    error
                });
            }
        );
    return newSeries;
}

export default forEachTasks;

标签: javascriptreactjsclient-serverapexcharts

解决方案


您可以useEffect挂钩并为您的组件添加一个新状态,当您按下submit按钮时该状态会发生变化。然后你只需要将状态添加到useEffect依赖数组中就可以了。

例如

useEffect(() => {
  // Add code that you want to run when hasChanged is updated
},[hasChanged])

推荐阅读