0
  • 对于 Js 和 React 的世界来说还是新手,我刚刚创建了一个可以运行的网站。但它让我感到困扰的是我让它工作的方式。我想深入了解如何以更好的方式做事。所以在这里我在沙盒上做了一个简单的项目来重现我所做的并问了几个问题。这是沙箱:https ://codesandbox.io/s/amazing-dream-oz8ec?file=/src/App.js

您将找到一个 console.log(tab) 来跟踪选项卡的演变。

  • 所以这里是对这个项目的快速解释,我有两个组件(Mario 和 Luigi),我想与之交互并做出反应(没有双关语),并对彼此进行修改。为此,我制作了一个对象数组,并将所述组件的特征放入每个对象中。然后,我使用我在 reducer 中构建的案例对对象数组进行更改。从另一个角度来看,我有马里奥和路易吉,我希望能够单击其中一个以使它们能够跳跃(通过创建一个我希望在其中一个可见性方面独占的“跳跃”按钮) ,然后点击“跳转”按钮,让其中一个跳转(这使得一个跳转在网页上全屏显示,另一个暂时不可见)。我最不想“退出”

所以这就是我迷路的地方。

  • 第一个问题:所以我有点理解改变现有状态(不重新渲染)和返回新状态(实际上是重新渲染)之间的区别。在我的第一种情况 'toggleCanJump' 中,突变 ( tab.map(hero => (hero.canJump = false));) 正在影响返回,因为它使我的选项卡的 canJump 值独占(一次只有一个可以为真),而在我的第二种情况下,'toggleJumped' 突变 ( tab.map(hero => (hero.canJump = false));) 不是影响数组,因此为什么在按钮的 className 中我有两个条件来建立类(className={hero.canJump && !hero.jumped ? "btn flex" : "btn"})?

要验证是否在第一种情况下返回之前对突变进行评论'toogleCanJump',您将看到它不再是排他性的,'canJump' 都可以具有值 true。即使有了突变,我也无法让“canJump”的价值对触发“跳跃”做出反应,即使突变如前所述。

  • 第二个问题:第一个问题有点多余。由于我似乎无法完全控制我的对象数组,因此当一个组件全屏显示而另一个组件显示为无时(例如:当马里奥在跳跃时,路易吉消失了)。我需要一个“重置”按钮来实际切换一个案例,该案例返回(字面意思是复制和粘贴)我的对象数组的初始值。我觉得它很笨拙,但由于我没有完全掌握我的数组的操作(如问题一所述),我找到了这个解决方案来使它工作。那么我如何能够在数组中正确地切片和重新插入我的对象?

这个问题与第一个问题类似,但在不同的情况下。我觉得我得到了变异和返回我的状态(对象数组)之间的区别,但我似乎无法使其有效。'toggleCanJump' 上的突变似乎有效,但 'toggleJumped' 上的突变实际上不起作用,并且正在返回选项卡,因为我声明它确实是重置它的最佳方式(更优雅的方式)?

我想补充一点,可能是我的逻辑不好!也许它应该是一个数组的数组,我发现对象对网站的未来更新更加健谈。但我不反对用其他方式来做。

如果您想找到解决方案或另一种做事方式。您的时间将不胜感激。感谢您的阅读。

4

1 回答 1

1

请参阅重新配置的沙箱:

https://codesandbox.io/s/cold-frost-x62x3?file=/src/App.js

关于第一个问题,您实际上是在使用 map ,就好像它是 forEach 并直接改变状态一样。Map 旨在返回一个新数组,其中您使用“=”将值等同于原始数组。

然而,只有一个似乎影响结果的事实是一种错觉(他们都这样做)并且是由不同的原因引起的。您的调度被多次触发-有些奇怪,有些甚至:抵消了效果。发生这种情况有两个原因:1. 你的 reducer 没有放在你的函数之外,2. 你的按钮是嵌套的,因此需要 e.stopPropagation()。

关于问题二,因为你的 hero.style 属性是唯一的,你需要创建一个对象映射来恢复它。由于字符已经硬编码到初始状态,因此更容易保留它。

于 2020-07-06T18:22:09.760 回答