[英]How can I initialize a class instance in a stateless function component in React?
Using a stateful pattern, I usually initialize a kind of helper class in my constructor and consume its methods in some component lifecycle methods like below:使用有状态模式,我通常在我的构造函数中初始化一种帮助器 class 并在一些组件生命周期方法中使用它的方法,如下所示:
class StatefulComponent extends Component {
constructor(props) {
super(props);
this.helper = new HelperClass();
}
componentDidMount() {
this.helper.doSomething();
}
}
Now, I wanted to convert the same logic into a stateless function component like this:现在,我想将相同的逻辑转换为无状态的 function 组件,如下所示:
const StatelessFunction = (props) => {
this.helper = new HelperClass();
useEffect(() => {
this.helper.doSomething();
}, []);
}
But I worried when I saw that this component is being called every prop change from the beginning.但是当我看到这个组件从一开始就被每个 prop 更改调用时,我很担心。 And this made me think that my class instance is being created over and over.
这让我觉得我的 class 实例正在一遍又一遍地创建。 Am I wrong?
我错了吗? Is there anything I can do for preventing re-creation of my class and use a ref instead?
我能做些什么来防止重新创建我的 class 并改用 ref 吗?
I came across useRef but not sure if it fits my case.我遇到了useRef但不确定它是否适合我的情况。
Looking back at this and some of the comments I can see that useMemo can not be trusted to not run the HelperClass constructor again and useRef will only set the helper after the first render because it's initial value can't be a function.回顾这个和一些评论,我可以看到不能相信 useMemo 不会再次运行 HelperClass 构造函数,并且 useRef 只会在第一次渲染后设置助手,因为它的初始值不能是 function。 Probably useState is the easiest and most reliable way to do this:
可能 useState 是最简单和最可靠的方法:
const [helper] = useState(()=>new HelperClass());
You can use useMemo to create an instance of HelperClass and useEffect to call it.您可以使用 useMemo 创建 HelperClass 的实例并使用 useEffect 调用它。 Giving them both empty array of dependencies means they will only be called "on mount".
给它们两个空的依赖数组意味着它们只会被称为“挂载”。 I put on mount in quotes because memo will be called only on first render and effect will be called after first render cycle is finished.
我将 mount 放在引号中,因为 memo 只会在第一次渲染时调用,而 effect 将在第一次渲染周期完成后调用。
const StatelessFunction = props => {
const helper = useMemo(() => new HelperClass(), []);
useEffect(() => {
helper.doSomething();
}, [helper]);
return (<JSX />);
};
If the only thing you'll ever do is just call doSomething and never use the helper instance again you can just do it with useEffect:如果您唯一要做的就是调用 doSomething 并且不再使用辅助实例,您可以使用 useEffect 来完成:
useEffect(() => {
new HelperClass().doSomething();
}, []);
If you do plan to use the helper instance at some later time then you could use the previous example with useMemo or useRef:如果您确实计划在以后使用帮助程序实例,那么您可以将前面的示例与 useMemo 或 useRef 一起使用:
const helper = useRef();
useEffect(() => {
helper.current = new HelperClass();
//only called once after first render
helper.current.doSomething();
}, []);
//you still have the helper instance as helper.current
I'd go for useMemo
solution, but here's how you can do it with useRef
+ useEffect
to clear up some confusion:我将 go 用于
useMemo
解决方案,但这是使用useRef
+ useEffect
来消除一些混乱的方法:
const StatelessFunction = (props) => { const helper = useRef(); // ref is equivalent of instance prop useEffect(() => { helper.current = new HelperClass(); helper.current.doSomething(); }, []); // this is equivalent of componentDidMount }
You are correct, useRef
allow you to have the same instance of HelperClass
persisted across re-renders你是对的,
useRef
允许你在重新渲染中保持相同的HelperClass
实例
const StatelessFunction = (props) => {
const helper = useRef(new HelperClass())
useEffect(() => {
helper.current.doSomething();
}, []);
}
just use useRef
, no need to combine it with useEffect
.只需使用
useRef
,无需将其与useEffect
结合使用。
const instance = useRef();
if (!instance.current) {
instance.current = new HelperClass();
}
see React Docs for details.有关详细信息,请参阅React 文档。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.