ReactJs:在对象数组上使用Reducer。我需要更多的理解
ReactJs : useReducer on array of object. I need more understanding
- 对 Js 和 React 的世界还是陌生的,我刚刚制作了一个可以运行的网站。但这让我感到困扰。我想深入了解如何以更好的方式做事。
所以在这里我在沙盒上做了一个简单的项目来重现我所做的并提出几个问题。
这是沙箱:https://codesandbox.io/s/amazing-dream-oz8ec?file=/src/App.js
您会找到一个 console.log(标签)来跟踪标签的演变。
- 所以这里是对该项目的快速解释,我有两个组件(Mario 和 Luigi),我想与之交互并做出反应(无双关语意)并相互修改。为此,我制作了一个对象数组,并将所述组件的特征放入每个对象中。然后,我使用我在 reducer 中构建的案例对对象数组进行更改。从另一个角度来看,我有马里奥和路易吉,我希望能够点击其中一个让他们能够跳跃(通过创建一个 'jump' 按钮,我希望在可见性方面独占其中一个他们),然后点击'jump'按钮让其中一个跳跃(这使得一个跳跃在网页上全屏显示,另一个暂时不可见)。最后我想要一个 'exit' 按钮(在跳跃时出现),它将我的值(数组的)重置为原始值。
这就是我迷路的地方。
- 第一个问题:所以我有点明白改变现有状态(不重新渲染)和return改变一个新状态(实际上重新渲染)之间的区别。在我的第一个案例中 'toggleCanJump'
突变 (
tab.map(hero => (hero.canJump = false));
) 正在影响 return 因为它使我的选项卡的 canJump 值独占(一次只有一个可以为真),而在我的第二种情况下 'toggleJumped' 突变(tab.map(hero => (hero.canJump = false));
) 不影响数组,因此为什么在按钮的类名中我有两个条件来建立 类 (className={hero.canJump && !hero.jumped ? "btn flex" : "btn"}
)?
为了验证在第一种情况 return 之前只对突变进行评论 'toogleCanJump' 你会发现它不再是排他性的 'canJump' 都可以具有值 true .然而,即使有了突变,我也无法实现 'canJump' 的值对触发 'jumped' 做出反应,即使突变如前所述起作用。
- 第二个问题:哪个和第一个有点多余。由于我似乎无法完全控制我的对象数组,当一个组件全屏显示而另一个显示为 none 时(例如:当马里奥跳跃时,路易吉消失)。我需要一个 'reset' 按钮来实际切换 returns(字面意思是复制和粘贴)我的初始值的情况
对象数组。我觉得它很笨拙,但由于我没有完全掌握我的数组的操作(如问题一所述),我找到了这个解决方案来使其工作。那么我怎样才能正确地将我的对象切片并重新插入到数组中呢?
这个问题和第一个问题有点相同,但场景不同。我觉得我明白了改变和 returning 我的状态(对象数组)之间的区别,但我似乎无法使其有效。 'toggleCanJump' 上的突变似乎起作用,但 'toggleJumped' 上的突变实际上不起作用,并且 return 正在使用选项卡,因为我宣布它确实是重置它的最佳方式(更优雅的方式)?
我想补充一点,可能是我的逻辑不对!或许应该是数组数组,我觉得object比较多嘴,方便以后网站的更新。但我不反对用其他方式来做。
如果您想找到解决方案或其他做事方式。非常感谢您的宝贵时间。感谢阅读。
查看重新配置的沙箱:
https://codesandbox.io/s/cold-frost-x62x3?file=/src/App.js
关于第一个问题,你实际上是把map当作forEach来使用,直接改变状态。 Map 旨在 return 一个新数组,因为您使用“=”将值等同于原始数组。
然而,似乎只有一个影响结果的事实是一种错觉(他们都这样做)并且是由不同的原因造成的。你的派遣被多次触发——有些奇怪,有些甚至:抵消影响。发生这种情况有两个原因:1. 你的 reducer 没有放在你的函数之外,2. 你的按钮是嵌套的,因此需要 e.stopPropagation().
关于问题二,因为你的hero.style属性是独一无二的,你需要创建一个对象映射来恢复它。它更容易保持原样,因为字符已经硬编码到初始状态。
- 对 Js 和 React 的世界还是陌生的,我刚刚制作了一个可以运行的网站。但这让我感到困扰。我想深入了解如何以更好的方式做事。 所以在这里我在沙盒上做了一个简单的项目来重现我所做的并提出几个问题。 这是沙箱:https://codesandbox.io/s/amazing-dream-oz8ec?file=/src/App.js
您会找到一个 console.log(标签)来跟踪标签的演变。
- 所以这里是对该项目的快速解释,我有两个组件(Mario 和 Luigi),我想与之交互并做出反应(无双关语意)并相互修改。为此,我制作了一个对象数组,并将所述组件的特征放入每个对象中。然后,我使用我在 reducer 中构建的案例对对象数组进行更改。从另一个角度来看,我有马里奥和路易吉,我希望能够点击其中一个让他们能够跳跃(通过创建一个 'jump' 按钮,我希望在可见性方面独占其中一个他们),然后点击'jump'按钮让其中一个跳跃(这使得一个跳跃在网页上全屏显示,另一个暂时不可见)。最后我想要一个 'exit' 按钮(在跳跃时出现),它将我的值(数组的)重置为原始值。
这就是我迷路的地方。
- 第一个问题:所以我有点明白改变现有状态(不重新渲染)和return改变一个新状态(实际上重新渲染)之间的区别。在我的第一个案例中 'toggleCanJump'
突变 (
tab.map(hero => (hero.canJump = false));
) 正在影响 return 因为它使我的选项卡的 canJump 值独占(一次只有一个可以为真),而在我的第二种情况下 'toggleJumped' 突变(tab.map(hero => (hero.canJump = false));
) 不影响数组,因此为什么在按钮的类名中我有两个条件来建立 类 (className={hero.canJump && !hero.jumped ? "btn flex" : "btn"}
)?
为了验证在第一种情况 return 之前只对突变进行评论 'toogleCanJump' 你会发现它不再是排他性的 'canJump' 都可以具有值 true .然而,即使有了突变,我也无法实现 'canJump' 的值对触发 'jumped' 做出反应,即使突变如前所述起作用。
- 第二个问题:哪个和第一个有点多余。由于我似乎无法完全控制我的对象数组,当一个组件全屏显示而另一个显示为 none 时(例如:当马里奥跳跃时,路易吉消失)。我需要一个 'reset' 按钮来实际切换 returns(字面意思是复制和粘贴)我的初始值的情况 对象数组。我觉得它很笨拙,但由于我没有完全掌握我的数组的操作(如问题一所述),我找到了这个解决方案来使其工作。那么我怎样才能正确地将我的对象切片并重新插入到数组中呢?
这个问题和第一个问题有点相同,但场景不同。我觉得我明白了改变和 returning 我的状态(对象数组)之间的区别,但我似乎无法使其有效。 'toggleCanJump' 上的突变似乎起作用,但 'toggleJumped' 上的突变实际上不起作用,并且 return 正在使用选项卡,因为我宣布它确实是重置它的最佳方式(更优雅的方式)?
我想补充一点,可能是我的逻辑不对!或许应该是数组数组,我觉得object比较多嘴,方便以后网站的更新。但我不反对用其他方式来做。
如果您想找到解决方案或其他做事方式。非常感谢您的宝贵时间。感谢阅读。
查看重新配置的沙箱:
https://codesandbox.io/s/cold-frost-x62x3?file=/src/App.js
关于第一个问题,你实际上是把map当作forEach来使用,直接改变状态。 Map 旨在 return 一个新数组,因为您使用“=”将值等同于原始数组。
然而,似乎只有一个影响结果的事实是一种错觉(他们都这样做)并且是由不同的原因造成的。你的派遣被多次触发——有些奇怪,有些甚至:抵消影响。发生这种情况有两个原因:1. 你的 reducer 没有放在你的函数之外,2. 你的按钮是嵌套的,因此需要 e.stopPropagation().
关于问题二,因为你的hero.style属性是独一无二的,你需要创建一个对象映射来恢复它。它更容易保持原样,因为字符已经硬编码到初始状态。