咱们先来假如一种场景:当进入页面时须要去申请获取初始数据,初始数据中有一个字段A,当A====true时须要弹出一个弹窗。
先封装一个弹窗组件,组件接口两个参数visible、close,visible管制是否显示弹窗,close用来敞开弹窗
import React from 'react';
import styles from './index.module.scss';
interface IProps {
visible: boolean;
close: () => void;
}
const Popup = (props: IProps) => {
const { visible, close } = props;
return (
visible ?
<div className={styles.container}>
<div className={styles.box}>
<p>确定要删除吗?</p>
<div>
<button onClick={close}>勾销</button>
<button>确认</button>
</div>
</div>
</div>
:
<></>
)
}
export default Popup;
而后在页面中调用
import { inject, observer } from 'mobx-react';
import React, { useEffect } from 'react';
import Store from '../stores/Store';
import Popup from './Popup';
interface IProps {
store?: Store;
}
const Main = (props: IProps) => {
const { store } = props;
const { visible, setVisible } = store as Store;
// 在dom挂在后執行
useEffect(() => {
setVisible(true) // 模仿申请,弹出弹窗
})
return <div>
<Popup visible={visible} close={() => setVisible(false)}></Popup>
</div>
}
export default inject('store')(observer(Main));
这里应用mobx@1.15.4,mobx-react@6.2.2,mobx6版本写法有变动
import { action, observable } from "mobx";
class Store {
@observable visible = true;
@action
setVisible = (visible: boolean) => {
this.visible = visible;
}
}
export default Store;
当运行我的项目时,会发现每次点击敞开弹窗,弹窗又立刻从新弹出。这是因为点击敞开时store
中的visible
发生变化,导致只有类组件render
办法或者函数组件return
中应用到visible
的组件都会从新渲染,从新渲染又会触发useEffect hooks
发送申请,如此循环,使得呈现上述景象。
那么如何解决上述问题呢?
如果能不触发useEffect hooks
是不是能够解决呢?不在内部传入visible以及close,而是在popup组件外部依赖store获取visible和close,这样父组件Main就不必从新渲染,进而useEffect hooks
也不必再次执行。
将popup组件实现形式改成如下:
import React from 'react';
import { inject, observer } from 'mobx-react';
import styles from './index.module.scss';
import Store from '../../stores/Store';
interface IProps {
store: Store;
}
const Popup = (props: IProps) => {
const { store } = props;
const { visible, close } = store as Store;
return (
visible ?
<div className={styles.container}>
<div className={styles.box}>
<p>确定要删除吗?</p>
<div>
<button onClick={close}>勾销</button>
<button>确认</button>
</div>
</div>
</div>
:
<></>
)
}
export default inject('store')(observer(Popup));
发表回复