将数据传递到现有应用程序中的 React 组件
Passing data into a React component within existing app
我有一个现有的 PHP 应用程序来管理产品。每个产品可以有多个图像。目前添加或删除图像的过程都是通过 PHP 服务器端处理的,因此需要在每个操作上加载页面。
由于这是一个现有的大型应用程序,我希望在整个过程中进行改进,其中之一是用 React 组件替换此图像 adding/removing 部分。
所以,我已经做到了。我创建了一个名为 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 在该组件之外添加和处理新图像。其他地方有一个按钮没有处理图像上传的页面和 returns 来自服务器的新文件名。
所以我的问题是,如何让我的 ImageManager 组件知道有新图像?组件似乎没有更改“data-js-images”属性。我猜这只读了一次,如果更新了就什么也没有发生。
如果我重新渲染组件并合并到我的新图像中然后将其传递给“data-js-images”属性那么它工作正常,但我觉得重新渲染整个组件不是“正确”的做法?
需要说明的是,没有顶级组件或类似的东西。
只有一个 app.js 文件和一堆 HTML.
如有任何帮助,我们将不胜感激!
谢谢
这里没有使用 useEffect 钩子,因为你只渲染一次组件并且不改变道具。您应该观察带有数据属性的 html 元素,当它发生变化时,您应该更新组件属性。
您可以使用 MutationObserver 构造函数,例如
const observer = new MutationObserver((mutations, observer) => {
// Do something when the element changes
});
observer.observe(element, {
attributes: true
});
我自己还没有测试过,但应该可以。
否则看看 this atricle
我有一个现有的 PHP 应用程序来管理产品。每个产品可以有多个图像。目前添加或删除图像的过程都是通过 PHP 服务器端处理的,因此需要在每个操作上加载页面。
由于这是一个现有的大型应用程序,我希望在整个过程中进行改进,其中之一是用 React 组件替换此图像 adding/removing 部分。
所以,我已经做到了。我创建了一个名为 ImageManager 的组件,并将其渲染为一个带有 id.
的 diveditProduct.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 在该组件之外添加和处理新图像。其他地方有一个按钮没有处理图像上传的页面和 returns 来自服务器的新文件名。
所以我的问题是,如何让我的 ImageManager 组件知道有新图像?组件似乎没有更改“data-js-images”属性。我猜这只读了一次,如果更新了就什么也没有发生。
如果我重新渲染组件并合并到我的新图像中然后将其传递给“data-js-images”属性那么它工作正常,但我觉得重新渲染整个组件不是“正确”的做法?
需要说明的是,没有顶级组件或类似的东西。 只有一个 app.js 文件和一堆 HTML.
如有任何帮助,我们将不胜感激! 谢谢
这里没有使用 useEffect 钩子,因为你只渲染一次组件并且不改变道具。您应该观察带有数据属性的 html 元素,当它发生变化时,您应该更新组件属性。
您可以使用 MutationObserver 构造函数,例如
const observer = new MutationObserver((mutations, observer) => {
// Do something when the element changes
});
observer.observe(element, {
attributes: true
});
我自己还没有测试过,但应该可以。 否则看看 this atricle