英文:
How to get rid of useEffect without changing the component's behavior?
问题
有一种趋势认为在React v18中应尽量减少使用useEffect
。
React文档说:
Effect允许您将组件与某些外部系统(例如聊天服务)同步。外部系统指的是任何不受React控制的代码。
然而,有许多情况下,我无法找到一种方法来移除useEffect
,而不影响组件的预期行为或使其看起来非常丑陋。
例如,下面的情况:
import { useEffect, useState } from "react";
interface SearchBarProps {
programType: "movies" | "series";
}
export function SearchBar({ programType }: SearchBarProps): JSX.Element {
const [searchTerm, setSearchTerm] = useState<string>("");
const [selectedYear, setSelectedYear] = useState<number | null>();
const [counter, setCounter] = useState<number>(0);
/*
当programType prop更改时重新设置searchTerm和selectedYear
*/
useEffect(() => {
searchTerm !== "" && setSearchTerm("");
typeof selectedYear === "number" && setSelectedYear(null);
}, [programType]);
const increase = () => {
setCounter(counter => counter + 1);
};
return (
<div className="search-bar">
<p>{searchTerm}</p>
<p>{selectedYear}</p>
<span className="counter__output">{counter}</span>
<div className="btn__container">
<button onClick={increase}>+</button>
</div>
</div>
);
}
有没有一种方法可以移除useEffect
而不影响组件的行为?
英文:
There is a trend saying that devs should get rid of useEffect as much as possible in React v18.
React documentation says
> An Effect lets you keep your component synchronized with some external
> system (like a chat service). External system means any piece of
> code that’s not controlled by React
However there are many situation where I can't find a way to remove the useEffect without making my component stop working as expected or look extremely ugly.
I.e. the case below:
import { useEffect, useState } from "react";
interface SearchBarProps {
programType: "movies" | "series";
}
export function SearchBar({ programType }: SearchBarProps): JSX.Element {
const [searchTerm, setSearchTerm] = useState<string>("");
const [selectedYear, setSelectedYear] = useState<number | null>();
const [counter, setCounter] = useState<number>(0);
/*
Restarts searchTerm and selectedYear when programType prop changes
*/
useEffect(() => {
searchTerm != "" && setSearchTerm("");
typeof selectedYear == "number" && setSelectedYear(null);
}, [programType]);
const increase = () => {
setCounter(counter => counter + 1);
};
return (
<div className="search-bar">
<p>{searchTerm}</p>
<p>{selectedYear}</p>
<span className="counter__output">{counter}</span>
<div className="btn__container">
<button onClick={increase}>+</button>
</div>
</div>
);
}
Is there any way of removing the useEffect without affecting the component behavior?
答案1
得分: 1
抱歉,你是对的,在 useEffect 中尝试调用它,像这样:
import { useEffect, useState } from "react";
interface SearchBarProps {
programType: "movies" | "series";
}
export function SearchBar({ programType }: SearchBarProps): JSX.Element {
const [searchTerm, setSearchTerm] = useState<string>("");
const [selectedYear, setSelectedYear] = useState<number | null>();
const [counter, setCounter] = useState<number>(0);
const handleProgramTypeChange = () => {
setSearchTerm("");
setSelectedYear(null);
};
const increase = () => {
setCounter(counter => counter + 1);
};
useEffect(() => {
handleProgramTypeChange();
}, [programType]);
return (
<div className="search-bar">
<p>{searchTerm}</p>
<p>{selectedYear}</p>
<span className="counter__output">{counter}</span>
<div className="btn__container">
<button onClick={increase}>+</button>
</div>
</div>
);
}
英文:
Im sorry, youre right, try calling it within the useEffect, like this:
import { useEffect, useState } from "react";
interface SearchBarProps {
programType: "movies" | "series";
}
export function SearchBar({ programType }: SearchBarProps): JSX.Element {
const [searchTerm, setSearchTerm] = useState<string>("");
const [selectedYear, setSelectedYear] = useState<number | null>();
const [counter, setCounter] = useState<number>(0);
const handleProgramTypeChange = () => {
setSearchTerm("");
setSelectedYear(null);
};
const increase = () => {
setCounter(counter => counter + 1);
};
useEffect(() => {
handleProgramTypeChange();
}, [programType]);
return (
<div className="search-bar">
<p>{searchTerm}</p>
<p>{selectedYear}</p>
<span className="counter__output">{counter}</span>
<div className="btn__container">
<button onClick={increase}>+</button>
</div>
</div>
);
}
答案2
得分: 0
我更新了代码,删除了useEffect
,并引入了一个名为handleProgramTypeChange
的新函数。每当programType
属性发生变化时,该函数被调用,直接将searchTerm
设置为空字符串,将selectedYear
设置为null
。这实现了与先前的useEffect
相同的行为,但不使用单独的效果钩子。
import { useState } from "react";
interface SearchBarProps {
programType: "movies" | "series";
}
export function SearchBar({ programType }: SearchBarProps): JSX.Element {
const [searchTerm, setSearchTerm] = useState<string>("");
const [selectedYear, setSelectedYear] = useState<number | null>();
const [counter, setCounter] = useState<number>(0);
const handleProgramTypeChange = () => {
setSearchTerm("");
setSelectedYear(null);
};
const increase = () => {
setCounter(counter => counter + 1);
};
return (
<div className="search-bar">
<p>{searchTerm}</p>
<p>{selectedYear}</p>
<span className="counter__output">{counter}</span>
<div className="btn__container">
<button onClick={increase}>+</button>
</div>
</div>
);
}
英文:
I updated the code, I removed the useEffect and introduced a new function called handleProgramTypeChange. This function is called whenever the programType prop changes, and it directly sets the searchTerm to an empty string and selectedYear to null. This achieves the same behavior as the previous useEffect, but without using a separate effect hook.
import { useState } from "react";
interface SearchBarProps {
programType: "movies" | "series";
}
export function SearchBar({ programType }: SearchBarProps): JSX.Element {
const [searchTerm, setSearchTerm] = useState<string>("");
const [selectedYear, setSelectedYear] = useState<number | null>();
const [counter, setCounter] = useState<number>(0);
const handleProgramTypeChange = () => {
setSearchTerm("");
setSelectedYear(null);
};
const increase = () => {
setCounter(counter => counter + 1);
};
return (
<div className="search-bar">
<p>{searchTerm}</p>
<p>{selectedYear}</p>
<span className="counter__output">{counter}</span>
<div className="btn__container">
<button onClick={increase}>+</button>
</div>
</div>
);
}
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论