如何在 ReactJS 中没有任何给定事件的情况下更新 UI [重复]

Posted

技术标签:

【中文标题】如何在 ReactJS 中没有任何给定事件的情况下更新 UI [重复]【英文标题】:How to update UI without any given event in ReactJS [duplicate] 【发布时间】:2019-05-02 17:15:53 【问题描述】:

我有一个 react 应用程序,我在其中渲染一些图片和 gif,用户可以将其附加到帖子中。

现在我在每个图像上都有一个onClick 处理程序,这样要么弹出模态操作,使用一些不同的选项,要么删除图片(如果用户按住 ctrl 键):

showModalSpeceficHandler = (event, image) =>
    let index = this.state.images.indexOf(image)
    if(event.ctrlKey)
     this.state.images.splice(index, 1);
 else
 this.setState(
     state => (imageModalData: image),
     () => this.showModalHandler()
 );

问题在于,如果满足第一个条件,则视图不会自动更新。而且我不能使用和箭头功能重新渲染,因为我在图像上使用了拼接方法。有没有办法让组件重新渲染,以便更新 UI?

我不确定是否应该将代码封装在 if 条件内、单独的处理程序内,还是可以使用箭头函数语法或类似的语法?

编辑:

我更新了方法,所以我动态设置了状态:

 if(event.ctrlKey)
      this.setState(
          state => (images: this.state.images.splice(index, 1))
      )

现在的问题是我想返回整个数组,而不仅仅是选定的图片。

【问题讨论】:

尝试使用 set state 而不是直接尝试改变 state -> this.state.images.splice(index, 1); 我投票结束这个问题,因为这是官方教程和文档的第一页所涵盖的基本 React 用法。 【参考方案1】:

问题是您没有正确更新状态。如果你想改变状态,无论如何你必须使用setState,否则 React 不知道它已经改变并且不会更新/渲染这些改变。有关详细信息,请参阅React documentation。

由于您需要从数组中删除一个元素,因此您必须制作一个临时/中间副本以进行修改,然后在 setState 函数中重新分配它:

let temp = this.state.images.slice(); //makes a shallow copy of the array
temp.splice(index, 1); //remove item
this.setState(prevState => ( images: temp )); //update state

【讨论】:

稍微不同地说,setState 是你告诉 React 事情发生了变化的方式。如果你不使用它,它不知道。 第一次调用 slice 时,会得到当前数组的副本,然后在移除索引后将状态设置为该数组? @baileyhaldwin slice() 允许您制作数组的浅表副本,这样您就不会直接修改状态。 splice() 然后从副本中删除所选索引处的项目。然后使用修改后的副本更新状态。【参考方案2】:

正如所说,你不能改变状态。如果这样做,组件将不会被重新渲染。在这种情况下,您可以做的只是在两种情况下都使用setState,并将splice 方法替换为filter

setState内部

images: state.images.filter(img => img !== image)

【讨论】:

以上是关于如何在 ReactJS 中没有任何给定事件的情况下更新 UI [重复]的主要内容,如果未能解决你的问题,请参考以下文章

如何在没有任何事件的情况下使用 react-router-dom 打开页面?

在ReactJS中使用迭代时如何将onClick事件传递给父组件?

如何在没有文本框的情况下获取键盘事件?

如何在没有事件的情况下获取鼠标位置(不移动鼠标)?

ReactJS如何在刷新页面时维护State值

typesafe 使用 reactjs 和 typescript 选择 onChange 事件