React table 显示 img 行时加载缓慢

React table slow loading when displaying img rows

我是 React 新手。我只是想构建一个 table 的数据,这些数据来自我获取的 API。但是现在我想将数据渲染成table。

我的问题是其中一列是来自 URL index.php?Action=GetLogo&id=51 的徽标。结果数超过 300。尽管我已经在使用分页,但 table 呈现速度很慢,尤其是 logo 列。所有数据都已加载,但我可以看到每个徽标都在逐行呈现,给用户带来缓慢的体验。

React 有什么办法可以解决这个问题吗?有人请指出正确的方向如何解决这个问题。

谢谢大家

更新 有人建议我使用 sync/await 函数来加载图像。然后我正在更新代码。但是,我的主要问题仍然存在:加载数据,尤其是徽标列。所有数据都被渲染,但徽标列没有渲染,然后每个徽标开始一个一个地渲染,看起来非常慢。我认为 async/await 函数可以缓解这种情况。

    import React from 'react';
    import ReactDOM from 'react-dom';
    import FormData from 'form-data';

    class FilterableSupplierTable extends React.Component {
        constructor(props) {
            super(props);
            this.state = {
                suppliers: []
            }
        }

        componentDidMount() {
            let formData = new FormData();
            formData.append('AjaxMethodName', 'GetSuppliers');
            const options = {
                method: 'POST',
                headers: {
                    'Accept': '*/*'
                },
                body: formData
            };
            fetch(`?Model=route_to_controller`, options)
                .then(response => response.json())
                .then(data => {
                    this.setState({ suppliers: JSON.parse(data.response_data) })
                });
        }

        async getLogos(suppliers) {
            return await Promise.all(
                suppliers.map(async supplier => {
                    supplier.new_logo = !!supplier.has_logo ?
                        <img style={{maxWidth: "100px"}} src={supplier.logo} alt={supplier.supplier_id} /> :
                        <i className="icon icon-warning no_logo">&nbsp;No Logo</i>;
                    return supplier;
                });
            );
        }

        render() {
            const rows = [];
            const suppliers = this.state.suppliers;
            this.getLogos(suppliers)
                .then(results => {
                    results.map(supplier => {
                        rows.push(
                            <tr>
                                {/* supplier.logo is index.php?Action=GetLogo&id=51, etc */}
                                <td><img src={supplier.new_logo} /></td>
                                <td>{supplier.name}</td>
                            </tr>
                        );
                    });
                });

            return (
                <table>
                    <thead>
                        <tr>
                            <th colSpan="4">Suppliers</th>
                        </tr>
                        <tr>
                            <th>Logo</th>
                            <th>Name</th>
                        </tr>
                    </thead>
                    <tbody>{rows}</tbody>
                </table>
            );
        }
    }
    ReactDOM.render(
        <FilterableSupplierTable />,
        document.getElementById('suppliers_list')
    );

您的问题可以通过更新 "global loading state".

的组件来解决

只有在 所有 图像更新完成加载后,它们才会一起显示:

function MyImage(props) {
  const onLoad = () => {
    props.onLoad();
  };

  return (
    <div>
      {props.isCurrentlyLoading && <div>Loading</div>}
      <img
        src={props.src}
        onLoad={onLoad}
        style={
          props.isCurrentlyLoading
            ? { width: "0", height: "0" } // You can also use opacity, etc.
            : { width: 100, height: 100 }
        }
      />
    </div>
  );
}

function ImagesBatch() {
  const [loadedImagesCounter, setLoadedImagesCounter] = useState(0);
  const [isAllLoaded, setIsAllLoaded] = useState(false);

  const updateLoading = () => {
    if (loadedImagesCounter + 1 === imagesUrls.length) {
      setIsAllLoaded(true);
    }
    setLoadedImagesCounter(prev => prev + 1);
  };

  return (
    <div>
      {imagesUrls.map((url, index) => {
        return (
          <MyImage
            key={url}
            src={url}
            index={index + 1}
            isCurrentlyLoading={!isAllLoaded}
            onLoad={updateLoading}
          />
        );
      })}
    </div>
  );
}

您可以查看完整代码 here(最好使用打开的控制台),我在其中使用了任意 ~6MB 图像作为示例。

我想你的问题已经解决了。但是,除此之外,我建议您查看 React Virtualized,https://github.com/bvaughn/react-virtualized

希望这对某一天有所帮助。