Skip to content

Instantly share code, notes, and snippets.

@Nkzn
Last active September 3, 2020 05:59
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save Nkzn/9aca904bd377e16e317124fd8a2787cc to your computer and use it in GitHub Desktop.
Save Nkzn/9aca904bd377e16e317124fd8a2787cc to your computer and use it in GitHub Desktop.
hooksで状態管理
import React from 'react';
function Hoge(props) {
const [count, setCount] = React.useState(0);
const [loading, setLoading] = React.useState(false);
const [error, setError] = React.useState(null);
const [onceLoaded, setOnceLoaded] = React.useState(false);
// 初回読み込み
React.useEffect(() => {
if (onceLoaded) {
return;
}
setOnceLoaded(true);
const init = async () => {
setLoading(true);
try {
const count = await fetchCount(); // 通信
setCount(count);
} catch (e) {
setError(e);
} finally {
setLoading(false);
}
};
init();
}, [onceLoaded]);
if (loading) {
return <div>loading...</div>;
}
if (error) {
console.error(error);
return <div>ERROR.</div>;
}
const onClickMinusOne = async () => {
const count = await updateCount(-1); // 通信
setCount(count);
};
const onClickPlusOne = async () => {
const count = await updateCount(1); // 通信
setCount(count);
};
return (
<div>
<div>{count}</div>
<button onClick={onClickMinusOne}>-1</button>
<button onClick={onClickPlusOne}>+1</button>
</div>
);
}
import React from 'react';
function Hoge(props) {
const [ increment, decrement, { count, loading, error } ] = useCounterService();
if (loading) {
return <div>loading...</div>;
}
if (error) {
console.error(error);
return <div>ERROR.</div>;
}
const onClickMinusOne = () => {
decrement();
};
const onClickPlusOne = async () => {
increment();
};
return (
<div>
<div>{count}</div>
<button onClick={onClickMinusOne}>-1</button>
<button onClick={onClickPlusOne}>+1</button>
</div>
);
}
// 状態管理だけを抽出したCustom Hooks
// プレフィックスのuse〜は慣例としてつけているが、他に命名上の制約は特にない
function useCounterService() {
const [count, setCount] = React.useState(0);
const [loading, setLoading] = React.useState(false);
const [error, setError] = React.useState(null);
const [onceLoaded, setOnceLoaded] = React.useState(false);
// 初回読み込み
React.useEffect(() => {
if (onceLoaded) {
return;
}
setOnceLoaded(true);
const init = async () => {
setLoading(true);
try {
const count = await fetchCount(); // 通信
setCount(count);
} catch (e) {
setError(e);
} finally {
setLoading(false);
}
};
init();
}, [onceLoaded]);
const decrement = async () => {
const count = await updateCount(-1); // 通信
setCount(count);
};
const increment = async () => {
const count = await updateCount(1); // 通信
setCount(count);
};
return [
increment,
decrement,
{
count,
loading,
error,
}
] as const;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment