【React】周期的な配列を管理したい
Q&A
Closed
解決したいこと
Reactで一定間隔ごとにAPIでデータを取得し、配列に追加することを考えています。単純に追加してしまうとデータがどんどん増えてしまうので、10件等の上限を決め、上限を超えたら1件目を上書きするような実装にしたいと考えてます。
- イメージ:
['data1', 'data2', ] // 1回目 ※API問い合わせ1回で、複数のデータが飛んでくる。
['data1', 'data2', 'data3', ] // 2回目
['data1', 'data2', 'data3', ] // 3回目 ※API問い合わせで、データ0件もあり得る。
['data1', 'data2', 'data3', 'data4', 'data5', ] // 4回目
['data6', 'data7', 'data3', 'data4', 'data5', ] // 5回目 ※上限を5件とした場合、6件目は1件目の場所を上書きする。
そこで、以下のCodePenのように実装したのですが、「test」ボタンを押した時の挙動が、
https://codepen.io/charon1212/pen/zYaLWqY
- 期待値
- 1回目…
[0,1,2,3,4]
と表示される。 - 2回目…
[0,1,2,3,4,0,1,2,3,4]
と表示される。 - 3回目…
[1,2,3,4,4,0,1,2,3,4,0]
と表示される。
- 1回目…
- 実際
- 1回目…
[4]
と表示される。 - 2回目…
[4,null,null,null,null,4]
と表示される。 - 3回目…
[4,null,null,null,null,4,null,null,null,null,4]
と表示される。
- 1回目…
となってしまっています。(※先ほでいう上限は、11件としており、0,1,2,3,4の5件データを複数回登録しています。)
1処理で同じStateのsetStateが複数回呼ばれていることに起因する問題だと思うのですが…
こういう時は、どう実装するのが良いか、知見をお持ちの方がいたらご教授頂きたいです。
該当するソースコード
念のため、CodePenの実装内容を下記に記載します。
const { Component, useState, useEffect, useContext, createContext } = React;
const useCycleArray = <T extends any>(mod: number) => {
const [list, setList] = useState<T[]>([]);
const [count, setCount] = useState(0);
const addList = (item: T) => {
const copy = [...list];
copy[count % mod] = item;
setList(copy);
setCount((p) => p + 1);
};
return [list, addList] as const;
};
const App = () => {
const [list, addList] = useCycleArray<number>(11);
const onClick = () => {
for (let i = 0; i < 5; i++) addList(i);
};
return (
<div>
<div><button onClick={onClick}>test</button></div>
<div>{JSON.stringify(list)}</div>
</div>
);
};
ReactDOM.render(<App />, document.querySelector(".container"));
0