質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

ただいまの
回答率

87.51%

ReactとamCharts、ボタンクリックをしても配列を追加できない

受付中

回答 1

投稿 編集

  • 評価
  • クリップ 0
  • VIEW 45

score 0

前提・実現したいこと

ReactにチャートライブラリamChartsの導入をしています。その上で、テキストtypeのinputタグに配列のアルファベット(配列データのcategoryに当たる部分)を入力し、ボタンtypeのinputタグをクリックした時に配列データを追加できるようにしたいのですが、なぜか追加されません。(クリックイベントはaddData)
原因は何でしょうか、
ご回答よろしくお願いします。

発生している問題・エラーメッセージ

エラーメッセージ

該当のソースコード

ソースコード
import React, { useLayoutEffect, useRef } from "react";
import { useState } from "react";
import * as am4charts from "@amcharts/amcharts4/charts";
import * as am4core from "@amcharts/amcharts4/core";
import am4themes_animated from "@amcharts/amcharts4/themes/animated";

am4core.useTheme(am4themes_animated);

function GanttChart ()  {

  const divRef = useRef(am4charts.XYChart);
  const chartRef = useRef(HTMLDivElement);
  const chartData = [
    {
      category: "A",
      id:"1",
      start: 1609462800000, // 2021-01-01 10:00:00
      end: 1609466400000 // 2021-01-01 11:00:00
    },
    {
      category: "B",
      id:"2",
      start: 1609473600000, // 2021-01-01 13:00:00
      end:   1609491600000 // 2021-01-01 14:00:00
    },
    {
      category: "C",
      id:"3",
      start: 1609473600000, // 2021-01-01 13:00:00
      end:   1609491600000 // 2021-01-01 14:00:00
    }
  ];

  const [data, changeData] = useState(chartData);

  const addData = () => {
    let value = document.getElementById("text").value;
    if(value === "") return;
    let next = data.length + 1;
    changeData(todos => [...todos, { id: next ,category: value}]);
    console.log(next);
    console.log(value);
    console.log(chartData);
  };

  useLayoutEffect(() => {
    if (divRef.current) {
      const chart = am4core.create(divRef.current, am4charts.XYChart);
      chart.height = 500;
      chart.paddingTop = 0;
      chart.paddingBottom = 0;
      chart.dateFormatter.dateFormat = "yyyy-MM-dd HH:mm:ss";
      chart.data = chartData;


      const dateAxis = chart.xAxes.push(new am4charts.DateAxis());
      dateAxis.extraMin = 0.1;
      dateAxis.extraMax = 0.1;
        dateAxis.renderer.labels.template.location = 0.0001;

      const categoryAxis = chart.yAxes.push(new am4charts.CategoryAxis());
      categoryAxis.dataFields.category = "category";
      categoryAxis.renderer.grid.template.location = 0;
      categoryAxis.renderer.inversed = true;

      const series = chart.series.push(new am4charts.ColumnSeries());
      series.dataFields.openDateX = "start";
      series.dataFields.dateX = "end";
      series.dataFields.categoryY = "category";
      series.columns.template.tooltipText = "category: {category} \n 開始: {openDateX} \n 終了: {dateX}";
      series.columns.template.tooltipPosition = "pointer";

      const scrollbar = new am4charts.XYChartScrollbar();
      chart.scrollbarX = scrollbar;
      scrollbar.series.push(series);

      chart.cursor = new am4charts.XYCursor();
      chart.scrollbarX = new am4core.Scrollbar();
      chart.scrollbarY = new am4core.Scrollbar();
      chart.plotContainer.events.on("doublehit", () =>
      dateAxis.zoom({ start: 0, end: 1 })
      );


      chartRef.current = chart;

      return () => chart.dispose();

    }
  }, [chartData]);


// useLayoutEffect(() => {

// }, [props.paddingRight]);

  return (
    <div>
      <div ref={divRef} style={{ height: 500, width: "85%"}} >
      </div>

      <input type="text" id="text"></input>
      <input type="button" onClick={addData}></input>
    </div>
  )
};

export default GanttChart

試したこと

addDataの中の”changeData(todos => [...todos, { id: next ,category: value}]);”を”changeData(data.concat({ id: next ,category: value}));”に変えて試したりもしましたが同じ結果になりました。

補足情報(FW/ツールのバージョンなど)

ここにより詳細な情報を記載してください。

  • 気になる質問をクリップする

    クリップした質問は、後からいつでもマイページで確認できます。

    またクリップした質問に回答があった際、通知やメールを受け取ることができます。

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 過去に投稿した質問と同じ内容の質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

質問への追記・修正、ベストアンサー選択の依頼

  • FKM

    2021/10/15 09:33

    value = document.getElementById("text").value
    この部分に対してvalueはちゃんと返ってきてますか?

    キャンセル

  • girafa

    2021/10/16 02:21 編集

    ご回答ありがとうございます!
    console.log(value)で確認しましたがそこにはしっかりと入力したものが返ってきました。

    キャンセル

回答 1

0

ReactはgetElementByIdは普通の方法では取得できません。したがって、valueを何も取得していない状態なので処理を中断(return)してしまいます。

Reactで、このように入力テキストと送信イベントの場所が異なる場合は、useStateフックを利用して以下のように対応します。

  import React, { useLayoutEffect, useRef,useState } from "react";
  const [val,setVal] = useState('')
  const addData = () => {
    let value = val //id="text"から取得した値
    if(value === "") return;
    let next = data.length + 1;
    changeData(todos => [...todos, { id: next ,category: value}]);
    console.log(next);
    console.log(value);
    console.log(chartData);
  };
/*中略*/

      <input type="text" id="text" onChange={(e)=>{setVal(e.target.value)} } value={val} />
      <input type="button" onClick={addData} />

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2021/10/16 02:27

    ご回答ありがとうございます!
    ご回答してくださったコードをそのまま入力してみましたが、結果として前と同じように配列の追加がうまくいきませんでした、、、
    何か他に原因がありますでしょうか、、、!

    キャンセル

15分調べてもわからないことは、teratailで質問しよう!

  • ただいまの回答率 87.51%
  • 質問をまとめることで、思考を整理して素早く解決
  • テンプレート機能で、簡単に質問をまとめられる

関連した質問

同じタグがついた質問を見る