【问题标题】:will cellmeasurer work for divs rendererd by dangerouslySetInnerHtmlcellmeasurer 是否可以通过 dangerouslySetInnerHtml 为 div 渲染器工作
【发布时间】:2018-03-18 09:32:14
【问题描述】:

我正在尝试创建具有动态行高的 List 原型。我正在尝试使用 CellMeasurer 来测量 rowHeights。我正在从服务器获取列表项的 html。它与 facebook 新闻提要中的某个项目有些相关。我需要动态确定我放置在下面提到的 rowRenderer 中的以下元素的高度。

   <div  style={style} key={key}>
   <div className={key}   style={style}  key={key}  >
   <div  dangerouslySetInnerHTML={{ __html: html2jsx }}></div>
   </div>

整个组件已复制如下:

    import React, { Component } from 'react';
    import ReactDOM from 'react-dom';
    import { List } from 'react-virtualized';
    import './FeedListView.css'
    import link from 'react';
    import { CellMeasurer, CellMeasurerCache, Grid } from 'react-virtualized';
    // List data as an array of strings
    class FeedListViewDynamicHeight extends Component {
    
    
      render() {
        const cache = new CellMeasurerCache({
          defaultWidth: 825,
           minWidth: 825,
           fixedHeight: true
        });
    
    
        function rowRenderer ({
          key,         // Unique key within array of rows
          index,       // Index of row within collection
          parent,   // This row is visible within the List (eg it is not an overscanned row)
          style        // Style object to be applied to row (to position it)
        }) {
          return (
    
                <CellMeasurer
                  cache={cache}
                  columnIndex={0}
                  key={key}
                  rowIndex={index}
                  parent={parent}
                  style={style}
                  >
    
    
             <div  style={style} key={key}>
             <div className={key}   style={style}  key={key}  >
             <div  dangerouslySetInnerHTML={{ __html: html2jsx }}></div>
              </div>
                   
                  </div>
    
    
    
    
       </CellMeasurer>
     );
    
        }
        return (
    
          <div>
    
          <List
          width={825}
          height={200}
          rowCount={1}
          rowHeight={cache.rowHeight}
          rowRenderer={rowRenderer}
          />
          </div>
    
    
        );
      }
    }
    

1.cellRenderer是否可以计算通过dangerousSetInnerHtml设置的行的高度? DangerouslySetInnerHtml 可以包含不同高度的图像/文本链接。

2.如果我确实给出了静态行高,我会看到很多空白空间,其中行大小实际上小于指定的 rowHeight。如何避免这种情况?

更新:

我将静态 html 代码更改为组件,然后尝试使用单元格测量器。高度被视为前 75 个组件的默认高度 30 像素,并且 CellMeasurer 似乎仅在超过高度参数时才起作用。附上截图和代码

  import React, { Component } from 'react';
  import ReactDOM from 'react-dom';
  import { List } from 'react-virtualized';
  import Post from './Post'

  import link from 'react';
  import styles from './main-header.css'
  import { CellMeasurer, CellMeasurerCache, Grid } from 'react-virtualized';



  import ReactHtmlParser, { processNodes, convertNodeToElement, htmlparser2 } from 'react-html-parser';
  // List data as an array of strings
  class FeedListViewDynamicHeight extends Component {

    _cache = new CellMeasurerCache({
      fixedWidth: true,
      });

    _rowRenderer = ({ index, isScrolling, key, parent, style }) => {



       var post={
         groupName:"Product Management- Discussions",
         postImageUrl:"https://media.licdn.com/mpr/mprx/0__DD-Wo-4z4cB8Q7d6jip7IyZB4eBiF_dFaPx7wanMDdqX6Ab5juODD0WydT",
         name:"Karan Thakral",
         role:"Worked at Cisco Systems",
         lastupdated:"2 mins ago",
         text:"Slack introduces shared channels to facilitate inter company chat, interesting developmenb Slack introduces shared channels to facilitate inter company chat, interesting developmen Slack introduces shared channels to facilitate inter company chat, interesting developmen Slack introduces shared channels to facilitate inter company chat, interesting developmen Slack introduces shared channels to facilitate inter company chat, interesting development",
         like:"0",
         comment:"1",
         share:"2"
         }

         let content;
          content=  <Post post={post}/>


      return (
        <CellMeasurer
          cache={this._cache}
          columnIndex={0}
          key={key}
          parent={parent}
          rowIndex={index}

        >

          // 'style' attribute required to position cell (within parent List)
          <div key={key} className={key} style={style}>
            {content}
          </div>
        

        </CellMeasurer>
      );
    };
    render() {







      return (

        <div>

        <List
        width={825}
        height={2000}
        rowCount={100000}
        rowHeight={this._cache.rowHeight}
        rowRenderer={this._rowRenderer}
      />
        </div>


      );
    }
  }

  export default FeedListViewDynamicHeight;

附上下面的截图

在图片中你可以看到从第 76 到 77div 的高度从 30px 到 481px 的变化?无法理解这个问题

【问题讨论】:

  • 列表元素维度未知时如何动态调整行大小?

标签: reactjs react-virtualized


【解决方案1】:

当我在另一个页面上呈现不同类型的列表时,我遇到了同样的问题。 我发布了 cache 在组件外部初始化。将缓存移入组件后,问题解决。

const DemoList = () => {
  const cache = new CellMeasurerCache({
    defaultHeight: 50,
    fixedWidth: true,
  });


  const rowRenderer = ({ index, key, parent, style }) => {
      const line = logs[index];
      const __html = convert.toHtml(line.message);
      const content = <div dangerouslySetInnerHTML={{__html: convert.toHtml(line.message)}} />
  }

    return (
      <CellMeasurer
        key={key}
        cache={cache}
        columnIndex={0}
        parent={parent}
        rowIndex={index}
      >
        {({ measure, registerChild }) => (
          <div ref={registerChild} style={style}>
            {content}
          </div>
        )}
      </CellMeasurer>
    );
  };


  return (
    <div style={{ flex: 1 }}>
      <AutoSizer>
        {({ height, width }) => (
          <List
            height={height}
            width={width}
            rowCount={logs.length}
            deferredMeasurementCache={cache}
            rowHeight={cache.rowHeight}
            rowRenderer={rowRenderer}
          />
        )}
      </AutoSizer>
    </div>
  );
}

【讨论】:

    【解决方案2】:

    1.cellRenderer是否可以计算通过dangerousSetInnerHtml设置的行的高度? DangerouslySetInnerHtml 可以包含不同高度的图像/文本链接。

    当然可以,但是您需要让CellMeasurer 知道在异步内容(如图像)完成加载后实际测量单元格。 CellMeasurer docs 展示了一个使用普通 React 渲染方法的示例:

    function rowRenderer ({ index, isScrolling, key, parent, style }) {
      const source // This comes from your list data
    
      return (
        <CellMeasurer
          cache={cache}
          columnIndex={0}
          key={key}
          parent={parent}
          rowIndex={index}
        >
          {({ measure }) => (
            // 'style' attribute required to position cell (within parent List)
            <div style={style}>
              <img
                onLoad={measure}
                src={source}
              />
            </div>
          )}
        </CellMeasurer>
      );
    }
    

    您需要修改示例以处理您直接设置 HTML 的事实。

    2.如果我确实给出了静态行高,我会看到很多空白空间,其中行大小实际上小于指定的 rowHeight。如何避免这种情况?

    不要听起来很时髦,但......不要这样做?如果您提供静态高度并且行更短,那么您当然会看到空白空间。你需要给出一个准确的高度。这就是CellMeasurer 存在的原因。 :)

    这是一个很好的参考组件:https://github.com/bvaughn/tweets/blob/master/src/components/TweetList.js

    它为我创建的演示假 Twitter 应用程序提供动力:https://tweets.now.sh/

    我建议查看源代码以获取类似新闻源列表的示例。

    【讨论】:

    • 嗨,Brian,感谢您的回复。目前,我将 html 更改为适当的反应组件,并尝试再次使用 CellMeasurer 运行。看到一个奇怪的行为。 rowHeight 的高度被视为 30px,根据代码,它是 defaultRowHeight,我看到所有组件的高度都在“height”参数的限制范围内。当 rowCount*rowHeight 与 height 参数相交时,组件的高度正在被正确计算。我用代码和截图更新了问题
    • 将我链接到一个 repro(CodeSandbox、Plnkr 等)。
    • 嗨,布赖恩,感谢您的回复。请找到 CodeSandbox 链接codesandbox.io/s/r1w5110p34
    • 潜在问题是您似乎通过onLoad 属性将measure 传递给Post 组件,该属性实际上并未在任何地方使用。即使使用了它,post 对象中的图像 URL 也是无效的,因此 &lt;img onLoad={...}&gt; 无论如何都不会被调用。这是一个使用 measure 回调并设置有效图像 URL 的分叉版本,以便触发它:codesandbox.io/s/92xvk9r6xo
    • 嗨,布赖恩,感谢您的回复。我的错误是我为 imageUrl 使用了错误的变量名。是否可以在有关使用度量的文档中包含更多带有异步数据的示例,这将非常有帮助。感谢您编写了一个很棒的库。
    猜你喜欢
    • 1970-01-01
    • 2021-09-16
    • 1970-01-01
    • 1970-01-01
    • 2011-06-09
    • 1970-01-01
    • 1970-01-01
    • 2014-05-26
    • 1970-01-01
    相关资源
    最近更新 更多