总的来说,我对 React hooks 还很陌生,对 React hooks 也很陌生useSelector
and useDispatch
in react-redux
,但我在执行一个简单的get
当我的组件加载时请求。我想要get
仅发生一次(当组件最初加载时)。我以为我知道如何做到这一点,但我遇到了 ESLint 问题,它阻止我执行我所理解的合法代码。
我有这个钩子,我试图抽象我的状态代码:
export const useState = () => {
const dispatch = useDispatch();
const data = useSelector((state) => state.data);
return {
data: data,
get: (props) => dispatch(actionCreators.get(props))
};
};
在上述函数的背后,有一个网络请求通过redux-saga
and axios
,并且已经在生产代码中运行了一段时间。到目前为止,一切都很好。现在我想在功能组件中使用它,所以我这样写:
import * as React from 'react';
import { useState } from './my-state-file';
export default () => {
const myState = useState();
React.useEffect(
() => {
myState.get();
return () => {};
},
[]
);
return <div>hello, world</div>;
};
我期望发生的是因为我的useEffect
有一个空数组作为第二个参数,它只会执行一次,所以get
当组件加载时就会发生,就是这样。
然而,我在 Atom 中保存时运行 ESLint,每次保存时,它都会改变那一秒[]
论证是[myState]
,其结果是:
import * as React from 'react';
import { useState } from './my-state-file';
export default () => {
const myState = useState();
React.useEffect(
() => {
myState.get();
return () => {};
},
[myState]
);
return <div>hello, world</div>;
};
如果我加载这个组件,那么 get 会运行每个渲染,这当然与我想要发生的情况完全相反。我在文本编辑器中打开了这个文件not在保存时运行 ESLint,所以当我能够保存时useEffect
有一个空白[]
, 有效。
所以我很困惑。我的猜测是我上面使用的模式不正确,但我不知道“正确”的模式是什么。
任何帮助表示赞赏。
Thanks!
UPDATE:
根据罗伯特·库珀的回答和丹·阿布拉莫夫的链接文章,我做了一些更多的实验。我还没有完全做到这一点,但我设法让事情顺利进行。
最大的变化是我需要添加一个useCallback
围绕我的调度功能,如下所示:
export const useState = () => {
const dispatch = useDispatch();
const data = useSelector((state) => state.data);
const get = React.useCallback((props) => dispatch({type: 'MY_ACTION', payload:props}), [
dispatch
]);
return {
data: data,
get: get,
};
};
我必须承认,我不完全理解为什么我需要 useCallback 那里,但它有效。
不管怎样,我的组件看起来像这样:
import * as React from 'react';
import { useState } from './my-state-file';
export default () => {
const {get, data} = useState();
React.useEffect(
() => {
get();
return () => {};
},
[get]
);
return <div>{do something with data...}</div>;
};
真正的代码有点复杂,我希望能够抽象出useEffect
完全调出组件并将其放入useState
自定义钩子,或从同一钩子导入的另一个钩子my-state-file
file.