ReactJS 组件渲染以及如何将元素附加到组件所在的 div

IT技术 reactjs
2021-05-13 23:58:47

我有一个用例,页面上有一个“加载更多”按钮可以从 API 端点获取更多项目,因此我希望这些项目在到达时附加到 DOM。问题是由 Web 服务器提供的 HTML 页面在item-list我安装 React 组件的同一个div 容器中带有一些额外的列表项(如下所示),在页面加载时带有空数据/props。

<div class="item-list">
  <div class="item-list__child-item"></div>
  <div class="item-list__child-item"></div>
  ...
  <div class="item-list__child-item"></div>
</div>

我的假设是,如果我以 ReactJS 的方式处理这个问题,一旦我从服务器 (REST) 获取更多项目并将这些项目附加到“itemList”状态数组中,React 就会以某种方式替换所有包含该内容的内容。 item-list' 组件所在的 div。

我认为可行的快速解决方法是创建一个具有相同 div 类名称“item-list”的单独同级 div,它不依赖同构的东西并在服务器上预渲染react组件并添加一个 id 属性来挂载组件,因此生成的 HTML 将如下所示:

<div class="item-list">
  <div class="item-list__child-item"></div>
  <div class="item-list__child-item"></div>
  ...
  <div class="item-list__child-item"></div>
</div>

<div class="item-list" id="react-component-name"></div>

也许有一种更简洁的方法可以在不涉及同构的东西的情况下做到这一点,或者我可能不理解 React 概念及其工作原理。无论如何,您将感激您对此的任何指示。

3个回答

好的,您的问题并不清楚,但是由 HTML 中生成的内容表示的数据将与您将通过 AJAX 获得的数据完全不同。

对此有一个简单的解决方案。您要做的不是创建一个与原始 DOM 布局相邻的全新 DOM 元素,而是获取已经存在的数据,将其存储到一个数组中,然后将您将通过 AJAX 获取的新数据附加到其中大批。这样,您将受益于 React 的 DOM diffing。为什么有用?也许你想让用户对数据进行排序,或者直接与数据交互,同时它仍然完全控制父 React 组件。

所以无论如何,看看这个小提琴:https : //jsfiddle.net/x4jjry04/3/它基于 Paul Booblic 的小提琴。

var Page = React.createClass({ 
  getDefaultProps: function () {
    return {
      items: []
    }
  },
  getInitialState : function(){
    return{
      items : this.props.items
    }
  },
  componentDidMount: function () {
    // Mimics an AJAX call, but replace this with an actial AJAX call.
    setTimeout(function () {
      var dataFromAjax = ['one', 'two', 'three'];
      this.setState({
        items: this.state.items.concat(dataFromAjax)
      });
    }.bind(this));
  },
  addClick : function(){
    this.state.items.push("more");
    this.forceUpdate();
  },
  render : function(){
    return <div>{this.state.items.map(function(item){return <div className="bla-bla-class">{item}</div>})}<br/><div onClick={this.addClick}>ADD</div></div>;
  }
});

var elements = document.querySelectorAll('.item-list__child-item');

var initialvalues = Array.prototype.slice
  .call(elements)
  .map(function (div) {
    return div.innerHTML;
  });

React.render(<Page items={initialvalues} />, document.body);

检查这个简单的小提琴演示:

https://jsfiddle.net/x4jjry04

var Page = React.createClass({ 
   getInitialState : function(){
   return{
    items : ["one","two","three"]
   }
  },
  addClick : function(){
   this.state.items.push("more");
   this.forceUpdate();

  },
  render : function(){
   return <div>{this.state.items.map(function(item){return <div className="bla-bla-class">{item}</div>})}<br/><div onClick={this.addClick}>ADD</div></div>;
  }
 });

React.render(<Page />, document.body);

我假设您正在使用 react serverside 来呈现列表?

在页面加载时,您从服务器获取原始列表并让组件“重新呈现”元素。重新渲染在引号中,因为除非列表发生变化,否则 React 实际上不会更新列表。现在您设置了一个按预期工作的组件,您可以根据需要将元素添加到列表中。

同构/通用 React 的一般理念是,您将应用程序视为普通的单页应用程序,并让 React 处理脏检查的魔力。

这也意味着您可以在服务器上渲染时使用相同的组件,因为您的组件不包含任何客户端特定的代码。