Use only one useEffect per page
- Bad
const [foo, setFoo] = useState("foo");
useEffect(() => {
setFoo("bar");
});
useEffect(() => {
setFoo("baz");
});
It is not clear which state would be updated.
- Good
const [foo, setFoo] = useState("foo");
const onClickBar = () => setFoo("bar");
const onClickBaz = () => setFoo("baz");
Instead, you should do away with the useEffect to prevent multiple updates.
In many cases, useEffect is not required. In reality, you use only one useEffect per page.
Events that occur in the browser are as follows:
- Page navigation, initial render, Path sifting, and so on.
- User events: click, tap.
-
EventListnerevent: Connecting or disconnecting from the network. - Event from server: WebSocket, real-time update from Firebase.
User events are not only required in useEffect. While most applications require page navigation or user events.
As a result, in many cases, useEffect requires page navigation.
Add a comment on the dependencies array in useEffect
- Bad: Load function
const [isLoaded, setIsLoaded] = useState<boolean>(false);
const [res, setRes] = useState();
const load = useCallback(async () => {
try {
if (isLoaded) {
return;
}
const fooApiRes = await FooApi();
setRes(fooApiRes);
} finally {
setIsLoaded(true);
}
}, [isLoaded]);
useEffect(() => {
load();
}, [load]);
If the props is a boolean, you should divide the component into different components
- Bad: A component includes both create and update
const DialogContents: React.FC<{isAdd: boolean}> = ({
isAdd: boolean,
}) => {
...
const onSubmit = useCallback(async () => {
if (isAdd) {
await FooRegisterApi();
return;
}
await FooUpdateApi();
}, []);
return (
<>
<form onSubmit={onSubmit}>
<label>Name</label>
<input value={name} onChange=>{onChangeName}/>
<label>ID</label>
<input disabled={!isAdd} value={id} onChange=>{onChangeId}/>
{isAdd &&
<label>Email</label>
<input value={email} onChange=>{onChangeEmail}/>
<label>PhoneNumber</label>
<input value={phoneNumber} onChange=>{onChangePhoneNumber}/>
}
</form>
</>
)
}
This codebase increases conditional statements as the app grows.
- Good: Divide the component into two components, such as a create component and an update component.
const RegisterDialogContents: React.FC = () => {
...
const onSubmit = useCallback(async () => {
await FooRegisterApi();
}, []);
return (
<>
<form onSubmit={onSubmit}>
<label>Name</label>
<input value={name} onChange=>{onChangeName}/>
<label>ID</label>
<input value={id} onChange=>{onChangeId}/>
<label>Email</label>
<input value={email} onChange=>{onChangeEmail}/>
<label>PhoneNumber</label>
<input value={phoneNumber} onChange=>{onChangePhoneNumber}/>
</form>
</>
)
}
const UpdateDialogContents: React.FC = () => {
...
const onSubmit = useCallback(async () => {
await FooUpdateApi();
}, []);
return (
<>
<form onSubmit={onSubmit}>
<label>Name</label>
<input value={name} onChange=>{onChangeName}/>
<label>ID</label>
<input disabled={true} value={id} onChange=>{onChangeId}/>
</form>
</>
)
}
Top comments (0)