通常使用状态模式,在构造函数中初始化一种辅助类,并在某些组件生命周期方法中使用其方法,如下所示:
class StatefulComponent extends Component {
constructor(props) {
super(props);
this.helper = new HelperClass();
}
componentDidMount() {
this.helper.doSomething();
}
}
现在,我想将相同的逻辑转换为这样的无状态函数组件:
const StatelessFunction = (props) => {
this.helper = new HelperClass();
useEffect(() => {
this.helper.doSomething();
}, []);
}
但是当我看到这个组件从一开始就被称为每个道具更改时,我感到担心。 这让我觉得我的类实例是一遍又一遍地创建的。 我错了吗?我可以采取什么措施来防止重新创建班级并改用ref?
我碰到了useRef,但不确定是否适合我的情况。
答案 0 :(得分:4)
您可以使用useMemo创建HelperClass的实例,并使用useEffect对其进行调用。给它们两个空的依赖性数组意味着它们将仅被称为“挂载”。之所以使用引号,是因为备忘录只会在第一次渲染时调用,而效果会在第一个渲染周期结束后调用。
const StatelessFunction = props => {
const helper = useMemo(() => new HelperClass(), []);
useEffect(() => {
helper.doSomething();
}, [helper]);
return (<JSX />);
};
如果您唯一要做的只是调用doSomething,并且不再使用辅助实例,则可以使用useEffect进行操作:
useEffect(() => {
new HelperClass().doSomething();
}, []);
如果您打算稍后再使用帮助程序实例,则可以将先前的示例与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
答案 1 :(得分:0)
我会寻求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
}
答案 2 :(得分:-1)
您是正确的,useRef
允许您在重新渲染时保留相同的HelperClass
实例
const StatelessFunction = (props) => {
const helper = useRef(new HelperClass())
useEffect(() => {
helper.current.doSomething();
}, []);
}