Javascriptのreduceメソッドに関してイマイチ使い方がつかめなかったのでインプットも兼ねて整理します。
Javascriptのreduceメソッドは、配列の要素を一つにまとめるメソッドです。
配列の全ての要素に対してコールバック関数を呼び出し、結果は単一の値となります。
例えば、配列内のすべての数値の和を計算するのに便利です。
例:配列の合計を求める場合
const numbers=[1,2,3,4];
const sum=numbers.reduce((accumulator,currentValue)=>accumulator+currentValue,0);
console.log(sum)
Reactでのreduceの活用例
配列のデータを集計して表示する
例えば、カートの合計金額を計算する場合
import React from "react";
const ShoppingCart = () => {
const cartItems = [
{ id: 1, name: "Apple", price: 100, quantity: 2 },
{ id: 2, name: "Banana", price: 50, quantity: 3 },
{ id: 3, name: "Orange", price: 80, quantity: 1 },
];
//item:現在の配列要素(ここでは商品のオブジェクト)
const totalPrice = cartItems.reduce((total, item) => total + item.price * item.quantity, 0);
return (
<div>
<h2>Shopping Cart</h2>
<ul>
{cartItems.map((item) => (
<li key={item.id}>
{item.name} x {item.quantity} = {item.price * item.quantity}円
</li>
))}
</ul>
<h3>Total: {totalPrice}円</h3>
</div>
);
};
export default ShoppingCart;
このコードは、配列cartItems内の各商品の合計金額を計算するものです。
reduceメソッドを使用して、各商品の金額(価格×数量)を累積していき、最終的にすべての商品の合計金額を算出しています。
reduceメソッドの注意点と解決方法
reduceメソッドは同期的に動作するため、非同期処理(Promise)を含む場合は動作しません。
そのため、非同期処理が含まれる場合はreduce関数を使わないほうがいいケースが多いです。
解決方法
①非同期処理を先に解決する(Promise.all を使用)か、for...of を使うことでシンプルに実装できる。
Promise.all は、JavaScriptで複数の非同期処理(Promise)を同時に実行し、すべての処理が完了したときに結果を一つの配列にまとめて返すメソッドです。
const areaIds = [1, 2, 3];
// 非同期関数: IDから名前を取得
const fetchAreaNameByAreaId = async (areaId) => {
return `AreaName${areaId}`; // 模擬データ
};
// 非同期処理を事前に解決
const areaNames = await Promise.all(
areaIds.map(async (areaId) => fetchAreaNameByAreaId(areaId))
);
// reduce を使用してデータを整形
const result = areaNames.reduce((acc, areaName) => {
acc.push(areaName);
return acc;
}, []);
console.log(result);
// ["AreaName1", "AreaName2", "AreaName3"]
②複雑な非同期処理を逐次実行する必要がある場合は、asyncReduce のようなカスタムロジックを使う。
非同期処理を逐次実行する必要がある場合、標準の reduce を使わずに、async/await を用いたカスタムの非同期版 reduce を作成します。
const asyncReduce = async (array, callback, initialValue) => {
let accumulator = initialValue;
for (let i = 0; i < array.length; i++) {
accumulator = await callback(accumulator, array[i], i, array);
}
return accumulator;
};