はじめに
JavaScriptのユーティリティライブラリの一つにLodashというものがあります。
業務で配列を扱うために使っていて、便利なので重宝しています。
しかし、配列操作以外にも便利なものが結構あることを知ったので、それらを紹介します。
debounce
概要
一度発火すると、一定時間は再発火されない関数を定義することができます。
フォームのユーザー入力によってAPIを呼び出す処理の場合に有効です。
基本形
_.debounce(func,wait,option)
func
実行したい処理を指定します。
wait
待機する時間を指定します。単位はミリ秒です。
option
オブションをオブジェクトの形式で指定します。
設定できるのは以下の3つのプロパティです。
{leading:boolean, maxWait:number, trailing:boolean}
今回は扱わないので、詳細は割愛します。
使用例
以下のような、入力結果に合わせてリアルタイムで検索するような画面があるとします。
入力フォームのonChange
イベントに検索処理を設定するかと思いますが、onChange
イベントは1文字入力するたびに発火するので、そのままだと少し使いにくいです。
そんなときにdebounce
を使います。
import { useState } from "react";
import _ from "lodash";
const LodashPractice = () => {
const [results, setResults] = useState<string[]>([]);
const handleSearch = _.debounce((term: string) => {
// 実際のAPI呼び出しをシミュレート
setResults([`Result for ${term}`]);
}, 300);
return (
<div>
<input
type="text"
onChange={(e) => handleSearch(e.target.value)}
placeholder="検索..."
/>
<ul>
{results.map((result, index) => (
<li key={index}>{result}</li>
))}
</ul>
</div>
);
};
export default LodashPractice;
debounceに実行したい処理を設定し、待機時間に300ミリ秒を指定したので、その間は入力値の変更があっても、処理は実行されません。
1文字ごとに検索処理が走るとちょっと使い勝手がわるいですが、これは若干待機の時間があるので、より使いやすいフォームになっています。
これとよく似た処理でthrottle
という関数があります。
今回は割愛しますが、こちらも便利なのでおすすめです。
get
概要
ネストされたオブジェクトの値を取得するために使います。
値が取得できなかった場合にデフォルト値を設定することができるので、不要な条件分岐を減らせます。
基本形
_.get(object,path,defaultValue)
object
取得元となるオブジェクトです。
path
プロパティを取得するためのパスです。
{ users:{ name:'taro', age:20 } }
このようなオブジェクトがあった場合、パスは
users.name
のような形になります。
配列を含んでいても取得可能です。
{ users:[ { name:'taro', age:20 }, { name:'jiro', age:15 } ] }
このようなオブジェクトがあった場合、パスは
users[0].name
のような形になります。
defaultValue
pathで指定したプロパティの取得結果がundefined
の場合に設定される値です。
使用例
ユーザー情報オブジェクトの中で、任意の設定プロパティがあるとします。
今回は、phone
が未設定のユーザー情報を画面に設定します。
import _ from "lodash";
interface User {
name: string;
contacts?: {
email?: string;
phone?: string;
};
}
const user: User = {
name: "Taro",
contacts: {
email: "taro@testmail",
},
};
const GetPractice = () => {
const email = _.get(user, "contacts.email", "なし");
const phone = _.get(user, "contacts.phone", "なし");
return (
<div>
<h2>{user.name}の連絡先</h2>
<p>Email: {email}</p>
<p>電話: {phone}</p>
</div>
);
};
export default GetPractice;
get
でデフォルト値を設定しているので、未設定があっても結果はエラーにならず、以下のように表示されます。
cloneDeep
概要
ネストされたオブジェクトの完全なコピーを作成することができます。
通常、ネストされたオブジェクトを複製するのは結構な手間がかかりますが、これを使うことで簡単にディープコピーが生成できます。
基本形
cloneDeep(object)
object
コピー対象のオブジェクトです。
使用例
以下のように、タスクをクリックすることで完了 / 未完了の切り替えをする簡易タスク管理アプリがあるとします。
タスクオブジェクトの配列をstate
で管理することになりますが、state
の更新のためには、新しい配列を生成する必要があります。
import { useState } from "react";
import _ from "lodash";
interface Task {
id: number;
title: string;
completed: boolean;
}
const CloneDeepPractice = () => {
const [tasks, setTasks] = useState<Task[]>([
{ id: 1, title: "タスク1", completed: false },
{ id: 2, title: "タスク2", completed: false },
{ id: 3, title: "タスク3", completed: false },
]);
const toggleTask = (id: number) => {
const newTasks = _.cloneDeep(tasks);
const task = newTasks.find((t) => t.id === id);
if (task) {
task.completed = !task.completed;
setTasks(newTasks);
}
};
return (
<ul>
{tasks.map((task) => (
<li key={task.id} onClick={() => toggleTask(task.id)}>
{task.title} - {task.completed ? "完了" : "未完了"}
</li>
))}
</ul>
);
};
export default CloneDeepPractice;
cloneDeep
を使うことで、余計な処理を書くことなく完全なコピーを作成できるため、簡潔に処理を実装することができました。
まとめ
lodashの関数で、配列操作以外で便利だなと思ったものを紹介しました。
ほかにもまだまだあるので、次回もlodashを扱います。