【问题标题】:ReactJS components rendering wrong orderReactJS 组件渲染顺序错误
【发布时间】:2016-03-04 16:55:48
【问题描述】:

这个问题有点啰嗦,但我想让你明白到底发生了什么......

我正在构建一个任务管理器桌面应用程序 (Electron) 供我们公司使用,但出现了一个奇怪的行为。任务管理器有 6 列(每个员工一列),包含要完成的任务的垂直列表。它包括拖放功能,因此您可以对任务进行排序。

我使用Dragula处理拖放部分,然后收集所有任务的ID号,从上到下依次存储在一个数组中。

我正在使用PouchDB 更新数据库并同步其他正在运行的应用程序。

对于 Dragula / PouchDB 方面,我使用以下代码:

var containers = [];
containers.push(ReactDOM.findDOMNode(this.refs.taskContainer));

var drake = Dragula(containers);
drake.on('drop', function(el, target, source, sibling) {

  // Get Desired Order of IDs
  for(i = 0; i < source.children.length; i++) {
    ids.push(source.children[i].id);
  }

  // Loop through IDs, write an "order" to tasks in PouchDB Database ("TaskData").
  // TaskData's replication is "live" so it automatically syncs to the DB.
  for(i = 0; i < ids.length; i++) {
    TaskData.get(ids[i]).then(function(doc) {   
      doc.order = ids.indexOf(doc._id);
      TaskData.put(doc).catch(function(err) {
        console.log(err);
      });
    });
  }

});

此时,我的 TaskData 现在有了一个新的“订单”键,其中包含所需的值。 现在,我需要渲染 ReactJS 组件 -- 按顺序

从 props 中获取任务(从 TaskData 刷新)并过滤掉需要的内容:

var tasks = this.props.tasks.filter(function(task) {
  if(task.archive !== 1) {
    return true
  }
});

然后我按上述订单号(使用 lodash.js)对任务进行排序,并将排序后的数据映射到 React 组件:

tasks = _.sortBy(tasks, 'order').map(function(task) {
  return <Task key={task.id} order={task.order} ...more props />
});

太好了,我的任务按顺序呈现,一切看起来都很好。

现在,问题...

当我拖放以将我的任务从["1", "2", "3", "4"] 重新排序到["4", "1", "2", "3"] 时,我实际上得到了["3", "4", "1", "2"]。任务移动和更新(因为上面的 Dragula / PouchDB 代码)。奇怪...我在开发工具中输入 location.reload(),令我惊讶的是,任务现在按我最初想要的顺序排列:["4", "1", "2", "3"]

再次尝试,我将任务从["1", "2", "3", "4"] 移动到["1", "3", "2", "4"],任务重置回["1", "2", "3", "4"]。同样,location.reload() 和任务现在已排序:["1", "3", "2", "4"]

在尝试调试时,我发现如果我禁用_.sortBy 功能,任务在被删除后会保持原状(尽管它们一开始就乱序)。任务移动到他们想要的位置并具有想要的订单号。

我还发现,如果我禁用 PouchDB .put(),并保持 _.sortBy 工作,它也可以工作,但数据不会写入服务器,因此订单号不会更新.

也许我只是盯着代码太久了,但我无法弄清楚为什么任务会跳来跳去。有人有什么想法吗?

感谢您的帮助!

【问题讨论】:

  • 是的,非常相似。希望我们中的一个人能得到答案,因为它可能会帮助另一个人。
  • 是的,这与我的帖子非常相似。从我可以看到我们的一致性是使用dragula、对项目进行排序以及重新渲染我们的组件。问题:您没有将重新订购的商品保存到状态,是吗?您只是得到一个任务列表,然后对新组件进行排序/映射,对吗?
  • @BDUB 我已经尝试过无数次尝试来解决这个问题。一种方法涉及获取任务道具,修改订单并将其存储为状态,但我也没有运气。目前,正如我上面的代码所示,我得到了传递下来的任务道具,然后我修改了顺序并在渲染函数中映射了组件。理想情况下,我会将这些移动到单独的函数中 - 但我试图首先让组件正常运行。
  • @Phillips126 看看这个:github.com/bevacqua/dragula/issues/188#issuecomment-139914022。我有一个很好的预感,dragula-react 和 react 不能很好地结合在一起。在 react 在 drop 事件上渲染您的组件之后,dragula 可能会重新排序项目。这是我正在追求的一条线索:在 drop 事件中进行所有数据操作,然后在 dragend 事件中进行渲染,以确保 Dragula 不再将它的手放在 cookie jar 中。我会告诉你的。

标签: reactjs lodash pouchdb dragula


【解决方案1】:

我通过实施uuid 设法让我的工作正常进行。下面是一个sn-p:

// Import the code
import uuid from 'uuid';

// My dummy component
<Messages>
  <ul>
    {messages.map(({ value, signature }) => (
      <Message 
        value={value}
        key={uuid.v4()} // use the uuid as the unique key
        from={signature}
        onMessageRecieved={this.handleMessageRecieved} />
    ))}
  </ul>
</Messages>

查看这些说明以了解有关实施的更多信息。 https://survivejs.com/react/getting-started/implementing-notes/

感谢@Alfthis link。帮助我解决了我的问题,请参阅@Dmitri Zaitsev's 答案。

快乐编码 =)

【讨论】:

    猜你喜欢
    • 2020-12-06
    • 2020-11-30
    • 1970-01-01
    • 1970-01-01
    • 2021-10-26
    • 2018-07-20
    • 2023-04-10
    • 1970-01-01
    • 2023-04-11
    相关资源
    最近更新 更多