boa*_*aol 5 reactjs react-hooks
我正在尝试使用 react hooks 构建一个 redux 进程,下面的代码是我想模拟一个ComponentDidMount带有 getUsers(redux action) 调用的函数,它是一个用于获取数据的 http 请求。
第一个版本是这样的
const { state, actions } = useContext(StoreContext);
const { getUsers } = actions;
useEffect(() => {
getUsers(); // React Hook useEffect has a missing dependency: 'getUsers'.
}, []);
Run Code Online (Sandbox Code Playgroud)
但我收到了一个 linting 警告“React Hook useEffect 缺少依赖项:'getUsers'。在 useEffect 中包含它或删除依赖项数组”,
然后我将 getUsers 添加到依赖项数组,但在那里得到了无限循环
useEffect(() => {
getUsers();
}, [getUsers])
Run Code Online (Sandbox Code Playgroud)
现在我通过使用 useRef 找到了解决方案
const fetchData = useRef(getUsers);
useEffect(() => {
fetchData.current();
}, []);
Run Code Online (Sandbox Code Playgroud)
不确定这是否是正确的方法,但它确实解决了掉毛和无限循环(暂时?)
我的问题是:在代码的第二个版本中,究竟是什么导致了无限循环?每次渲染后,依赖数组中的 getUsers 是否更改?
jpe*_*erl 10
你的函数有依赖项,React 认为不列出这些依赖项是不安全的。假设您的函数取决于名为users. 显式列出依赖项数组中的隐式依赖项是行不通的:
useEffect(() => {
getUsers();
}, [users]); // won't work
Run Code Online (Sandbox Code Playgroud)
然而,React 表示,推荐的解决方法是将函数移动到函数内部useEffect()。这样,警告不会说它缺少getUsers依赖项,而是依赖项getUsers。
function Example({ users }) {
useEffect(() => {
// we moved getUsers inside useEffect
function getUsers() {
console.log(users);
}
getUsers();
}, []); // users dependency missing
}
Run Code Online (Sandbox Code Playgroud)
因此,您可以指定users依赖项:
useEffect(() => {
function getUsers() {
console.log(users);
}
getUsers();
}, [users]); // OK
Run Code Online (Sandbox Code Playgroud)
但是,您是从 props 获取该功能,它没有在您的组件中定义。
那该怎么办呢?解决您的问题的方法是记住您的功能。
useCallback 将返回回调的记忆版本,该版本仅在依赖项之一发生更改时才会更改。这在将回调传递给依赖引用相等的优化子组件时很有用,以防止不必要的渲染(例如 shouldComponentUpdate)。
你不能在你的组件中记住它,因为会有同样的警告:
const memoizedGetUsers = useCallback(
() => {
getUsers();
},
[], // same warning, missing the getUsers dependency
);
Run Code Online (Sandbox Code Playgroud)
解决方案是在getUsers定义的地方记住它,然后您将能够列出依赖项:
// wrap getUsers inside useCallback
const getUsers = useCallback(
() => {
//getUsers' implementation using users
console.log(users);
},
[users], // OK
);
Run Code Online (Sandbox Code Playgroud)
在您的组件中,您将能够执行以下操作:
const { getUsers } = actions; // the memoized version
useEffect(() => {
getUsers();
}, [getUsers]); // it is now safe to set getUsers as a dependency
Run Code Online (Sandbox Code Playgroud)
至于存在无限循环的原因以及 useRef 工作的原因。我猜你的函数会导致重新渲染,并且在每次迭代时,都会重新创建 getUsers 并以无限循环结束。useRef 返回一个对象{ current: ... },使用 useRef 和{ current: ... }自己创建这个对象的区别在于useRef返回相同的对象而不是创建另一个对象。所以你可能使用了相同的功能。
小智 1
您应该在 useEffect 中声明 getUsers 它是您调用 getUsers 的唯一地方
useEffect(() => {
const { getUsers } = props;
getUsers();
}, []);
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
5166 次 |
| 最近记录: |