将数据传递到现有应用程序中的 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