【发布时间】:2022-01-07 15:14:27
【问题描述】:
我有一个管理产品的现有 PHP 应用程序。每个产品可以有多个图像。目前添加或删除图像的过程都是通过 PHP 服务器端处理的,因此每个操作都需要加载页面。
由于这是一个现有的大型应用程序,我希望对其进行改进,其中之一是用一个反应组件替换这个图像添加/删除部分。
所以,我确实做到了。我创建了一个名为 ImageManager 的组件并将其渲染为一个带有 id 的 div。
editProduct.html.twig
<div id="image-manager" data-js-images="{images: ['1.jpg', '2.jpg', '3.jpg']}"></div>
app.js
// Grab element & props
const element = document.getElementById('image-manager');
const props = element.dataset;
// Render it
ReactDOM.render(<ImageManager {...props} />, element);
到目前为止很简单。这是我的组件... ImageManager.js
import React, {Fragment, useState, useEffect} from 'react';
const ImageManager = ({jsImages}) => {
const [images, setImages] = useState([]);
// When jsImages changes
useEffect(() => {
setImages(jsImages);
}, [jsImages]);
return (
<Fragment>
<div className="row">
{images.map((img, idx) => {
return (
<div key={idx} className="col-2">
<img src={img}/>
<button type="button" className="btn btn-danger" onClick={() => {
// Remove it
const imagesCopy = [...images];
imagesCopy.splice(idx, 1);
setImages(imagesCopy);
}}>Remove</button>
</div>
);
})}
</div>
</Fragment>
);
};
export default ImageManager;
这一切都很好,但是......我遇到的问题是一些常规的非反应 JS 在此组件之外添加和处理了新图像。处理图片上传并从服务器返回新文件名的页面没有其他地方的按钮。
所以我的问题是,如何让我的 ImageManager 组件知道有一个新图像?似乎组件没有选择更改“data-js-images”属性。我猜这只会被读取一次,如果更新则什么都不会发生。
如果我重新渲染组件并合并到我的新图像中,然后将其传递给“data-js-images”属性,那么它工作正常,但我觉得重新渲染整个组件不是“正确的” " 这样做的方法?
需要明确的是,没有顶级组件或类似的东西。 只有一个 app.js 文件和一堆 HTML。
任何帮助将不胜感激! 谢谢
【问题讨论】:
-
不确定我的建议是否有效,但既然你说新图像是在 vanilla js 中处理的,你为什么不尝试在那里处理图像事件的变化并基于此渲染您的反应组件?
-
我确实是这样实现的,这样当添加新图像时,它会有效地破坏现有的 div 并重新渲染组件。它确实有效,但这感觉有点不对劲。我很感激考虑到我想要实现的目标,没有真正需要过于挑剔,我只是想确保我以正确的方式做到这一点。
-
在您使用的 react 组件中使用 useEffect (即使它不能正常工作,因为答案解释正确),它只会在每次图像更改时重新渲染组件。所以无论哪种方式,你都会重新渲染你的组件。在反应中做这件事完全没问题。
标签: javascript reactjs react-component