共计 1876 个字符,预计需要花费 5 分钟才能阅读完成。
咱们先来假如一种场景:当进入页面时须要去申请获取初始数据,初始数据中有一个字段 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));
正文完