react图片查看器插件images-viewer-react与useRef的爱与恨

0. 缘起

啊好久没写博文了,一方面是没空(换了个萝卜坑),另一方面是刚接触react,有些东西也不知道嘛意思,所以边看边想。最近就遇到这个图片查看器插件和current不会引发组件重新渲染的事儿。

1. images-viewer-react使用要点

1.1 官网

images-viewer-react - npm (npmjs.com)

              visible	可见性
              noClose	去除关闭按钮
              noNavbar	消去下方导航栏(图片缩略集)
              zoomable	是否放缩
              rotatable	是否旋转
              scalable	是否显示缩放按钮
              images	图片源
              defaultImg图片加载失败显示的默认图片
              container	inline 模式的容器(可以理解为画框,盛放当前图片查看器的元素)

1.2 重点——容器

如果不设置容器,图片查看器就会全屏显示,显然这不方便使用。

  import Viewer from 'images-viewer-react';

  // 图片查看器容器
  const [pictureBox, setPictureBox] = useState();
  
  // ...
        {originImgVisible && (
        <Modal title="原图查看" width={900} visible footer={null} onCancel={onCancel}>
          <div
            style={{
              width: 835,
              height: 600,
              backgroundColor: '#fff',
            }}
            ref={(e) => {
              setPictureBox(e);
            }}
          />
          {pictureBox && drawerData && (
            <Viewer
              visible
              noClose
              noNavbar
              zoomable={originImgVisible}
              rotatable={originImgVisible}
              scalable={originImgVisible}
              images={drawerData}
              defaultImg={defaultImg}
              container={pictureBox}
            />
          )}
        </Modal>
      )}

再继续讲这个画框容器怎么放的之前,来整一个新玩意儿——useRef。

2. useRef与ref

Hook API 索引 – React (reactjs.org)

请记住,当 ref 对象内容发生变化时,useRef不会通知你。变更 .current 属性不会引发组件重新渲染。如果想要在 React 绑定或解绑 DOM 节点的 ref 时运行某些代码,则需要使用回调 ref 来实现。

2.1 错误操作

我之前写的是这样的

const container = useRef()

 {container.current && drawerData && (
            <Viewer
              visible
              noClose
              noNavbar
              ...

logcontainer.current的时候一直显示undefined

  1. 初始化 container: undefined
  2. 点击按钮 显示弹窗 container: null
  3. 点击弹窗关闭按钮
container:  <div style=​"width:​ 835px;​ height:​ 600px;​ background-color:​ rgb(255, 255, 255)​;​">​</div>​

也就是说,在弹窗显示的时候container.current值为空,画框区域为空,所以啥也没显示。

2.2 正确操作

如果使用const [pictureBox, setPictureBox] = useState(),直接设置divref。此时效果为弹窗显示时,ediv的HTML元素,弹窗关闭时,enull

3. 加入antd组件

3.1 Antdv3版本的modal报错

react18版本不再支持unstable_renderSubtreeIntoContainer,而antdv3中的modaldrawer都用到这个方法,所以有红字报错

ReactDOM.unstable_renderSubtreeIntoContainer() is no longer supported in React 18. Consider using a portal instead. Until you switch to the createRoot API, your app will behave as if it's running React 17.

3.2 用visible属性值控制

useRef的值是一直存在的

	const ButtonGroup = Button.Group;
	const modalOutRef = useRef()
	const modalInRef = useRef()
	const drawerOutRef = useRef()
	const drawerInRef = useRef()
	console.log('modalOutRef: ', modalOutRef, 'in', modalInRef);
	console.log('drawerOutRef: ', drawerOutRef, 'in:', drawerInRef);
	
	// ...
				<ButtonGroup>
				<Button onClick={() => setModalVisible(true)}>Modal</Button>
				<Button onClick={() => setDrawerVisible(true)}>Drawer</Button>
			</ButtonGroup>
			<Modal
				ref={modalOutRef}
				title="Basic Modal"
				visible={modalVisible}
				onOk={closeWindow}
				onCancel={closeWindow}
			>
				<p ref={modalInRef}>Some contents...</p></Modal>
			<Drawer
				ref={drawerOutRef}
				title="Basic Drawer"
				placement="right"
				closable={false}
				onClose={closeWindow}
				visible={drawerVisible}
			>
				<p ref={drawerInRef}>Some contents...</p>
				<p>Some contents...</p>
				<p>Some contents...</p>
			</Drawer>

3.3 用modalVisible控制组件是否渲染

			{modalVisible && (<Modal
				ref={modalOutRef}
				title="Basic Modal"
				visible
				onOk={closeWindow}
				onCancel={closeWindow}
			>
				<p ref={modalInRef}>Some contents...</p></Modal>)}

就出现了之前说过的关闭才显示ref关联的奇怪BUG!!!drawer组件也是同样效果

posted @ 2022-05-07 16:27  乐盘游  阅读(896)  评论(0编辑  收藏  举报