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

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

新規登録して質問してみよう
ただいま回答率
85.35%
JavaScript

JavaScriptは、プログラミング言語のひとつです。ネットスケープコミュニケーションズで開発されました。 開発当初はLiveScriptと呼ばれていましたが、業務提携していたサン・マイクロシステムズが開発したJavaが脚光を浴びていたことから、JavaScriptと改名されました。 動きのあるWebページを作ることを目的に開発されたもので、主要なWebブラウザのほとんどに搭載されています。

React.js

Reactは、アプリケーションのインターフェースを構築するためのオープンソースJavaScriptライブラリです。

Q&A

解決済

1回答

1389閲覧

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

vivian

総合スコア1

JavaScript

JavaScriptは、プログラミング言語のひとつです。ネットスケープコミュニケーションズで開発されました。 開発当初はLiveScriptと呼ばれていましたが、業務提携していたサン・マイクロシステムズが開発したJavaが脚光を浴びていたことから、JavaScriptと改名されました。 動きのあるWebページを作ることを目的に開発されたもので、主要なWebブラウザのほとんどに搭載されています。

React.js

Reactは、アプリケーションのインターフェースを構築するためのオープンソースJavaScriptライブラリです。

0グッド

0クリップ

投稿2021/10/14 08:08

編集2021/10/14 08:14

前提・実現したいこと

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/ツールのバージョンなど)

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

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

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

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

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

FKM

2021/10/15 00:33

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

2021/10/15 17:22 編集

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

回答1

0

ベストアンサー

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

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

js

1 import React, { useLayoutEffect, useRef,useState } from "react"; 2 const [val,setVal] = useState('') 3 const addData = () => { 4 let value = val //id="text"から取得した値 5 if(value === "") return; 6 let next = data.length + 1; 7 changeData(todos => [...todos, { id: next ,category: value}]); 8 console.log(next); 9 console.log(value); 10 console.log(chartData); 11 }; 12/*中略*/ 13 14 <input type="text" id="text" onChange={(e)=>{setVal(e.target.value)} } value={val} /> 15 <input type="button" onClick={addData} /> 16

投稿2021/10/15 08:15

FKM

総合スコア3647

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

vivian

2021/10/15 17:27

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

2021/10/16 01:02

valueは取得できているのでしょうか?
vivian

2021/10/16 02:46

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

2021/10/16 02:50

オブジェクトのリアクティブ処理も変な気がします。基本オブジェクトで同期を取りたい場合 const [hoge,setHoge] = useState([]) setHoge(同期を取りたいオブジェクトの値) こうなるはずです。 changeData(todos => [...todos, { id: next ,category: value}]); となっていますが、todosはどこから出てきたオブジェクトなんでしょうか?
vivian

2021/10/16 03:07

大変失礼いたしました、、、!ありがとうございます! 自分が参考にしていた資料と同じような書き方をしてしまいました、 以下のようにリトライしてみました、結果は同じでした、、、。 const [data, changeData] = useState(chartData); changeData(data => [...data, { id: next ,category: value}]);
FKM

2021/10/16 03:11

その関数実行後のdataがどんな風に代入されているか確かめてみては? 多分自分の記憶では書き方が違う気が…
vivian

2021/10/16 03:58

ありがとうございます!もう少し確かめながら進めてみます!
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.35%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問