Hooks API - Avoid state overwrite when setting state after await statement - reactjs

Let's say we have a tile grid with the follow behavior:
There's a button for adding a tile. The tile will decide if it should be a red or blue tile after some time thinking (1-3secs). The tile will be green while it's thinking what color it should be.
Clicking a title will remove the tile from the grid
Let tiles be an array of tile colors which will serve as the state of the tile grid and setTiles as the setter of that state. Given the grid behavior, setTiles should be called during these events:
on click of a tile. The clicked tile should be removed from tiles.
on click of the add button. A green tile must be added to tiles.
after a tile decides what it's color is. The corresponding green value in tiles must be changed to red or green.
I've prepared a codepen of a simple implementation of the grid detailed above. The issue with this is that calls to setTiles after an await statement overwrites state changes that happened between the start and end of the asynchronous statement. I think this is because the function only has reference to the state value before starting the async operation.
What's the best architecture (component changes, callback passing, tile data structure), using SFCs and the Hooks API, to avoid the unintended overwrites and, ultimately, the tile grid having an updated array of tile data at all times?

Solved it by using useReducer. Wasn't aware that with useReducer, you have a "synchronised" state for all dispatched actions. The state overwrite wasn't an issue with the seemingly-central state with reducers. Working code here.

Related

How to trigger an event when an element intersects another element?

I am stuck on implementing a UI in React.
I want to trigger a state change when an element crosses the centre of the viewport.
Here's a prototype of the design: https://cln.sh/sNhueq
In this prototype, the box on the right is sticky so it stays on the screen. And the list on the left moves as we scroll. I want to know when a list item crosses that red line so I can change the content of the box.
I am using framer-motion and react-intersection-observer.
Here's what I tried:
I tried using the viewport prop of <motion.div> but it triggers when the element enters the whole viewport. Yes, we can set root prop to an element's ref but for that the root element has to be an ancestor which the red line is not.
I tried react-intersection-observer but got the same results (because the ancestor limitation comes from the IntersectionObserver API in general).
I ultimately thought of some hacky non-performant ways like having a scroll listener, checking the bounds of root and target and finding if they collide. But I really don't want to do that heavy computing.
Is there any way with IntersectionObserver or something else that is performant?
Any help is appreciated. Thank you! :)

Check if an element is in center in React

I'm implementing a carousel and I want to target the element at the center of the slider. So, I can make it pop a little.
How can I target this component? I have found ways to know if the element is inside the viewport or not but I want to know if it's horizontally centered.
Original Problem
Horizontal scroll and set state
Since you have no code my answer will be more theoretically how to do it.
So first off you should have a boolean state that you can toggle for the active state. This state should be controlled by the container. That way you can only activate one at a time.
Next you should get 2 values, the X scroll position of the container and the center point of the visible area of the gallery.
Then you can just calculate an offset on mount and then X scroll of the gallery.
So in theory it starts at 0 and your container is 500px you know that the active slide is at the 250px mark so you can calculate that with the position of the slide, it should be the last slide that passed that point. then just recalculate this value on scroll. (maybe throttle)
Possibly able to use react-hook-inview
I've used this react hook before on the Y axis. I'm not 100% sure that it works on the X scroll. But it can be a great way to trigger a state change on each of the slides. The only issue is that you'll be adding a event listener to each of your slides (possible performance hit).
You can see that lib here
This one lets each slide control it's own inView state.

Change element style without calling render method

I would like to create React app where you import, move and resize images on the screen and then export their positions. My idea was that I would have image as a component that would have its own attributes like positions, width, height and source. The problem is that I don't want to render new image element every time the component change its state (position, size, etc.) since it can be slow to load the image. I just want to change its style. Is there some React fashion approach how to do it? Thank you!
Maybe for your problem might be usefull to look life cycle update component...because it gives you some certain pattern to re-render a component in your own way..try to read something on "componentShouldUpdate()" this method give you a way to re-render the component only certain condition.
maybe here might be right for you: https://www.toptal.com/react/optimizing-react-performance
My best

Continuous requestAnimationFrame in React

I'm working on some sort of 'continuous' animation. Say a div translates from its current location 200px to the right. There's an option to change the distance of translation. While its animating, the user changes from 200px to 400px. The div should still move smoothly until it reaches its final point which is 400px from its previous location. I have done the basic moving animation, however I can't figure out how to make it continues without jumping when the distance changes.
Here's the codesandbox that I'm working on which best illustrates my point above and what I'm struggling with. Any ideas or help would be greatly appreciated. Thanks :))
Edit: Steps to reproduce the jumping problem:
Open the sandbox
Click the 'Toggle' button
Click the 'Add distance' button
While the red div animates, click 'Add distance' button again
And you should see the div jumping
There is probably a way to fix your code so that it works as you want, though I would suggest going in another direction. There are several animation libraries in React that can help you solve this problem. The resulting code is also going to be more portable.
For your specific need, I would suggest using a library called react-move. It is part of the react-tools which provides other cool libraries. I created a CodeSandbox with my take on your problem using react-move.
I only took the transform line for your code, since I wanted to focus on how you could integrate the library into your example.
To create the animation, I imported a component from react-move called Animate. It's the main component of the library. You use this component to wrap a function using the function as child pattern. This function will receive a state object with information regarding the animated element. It also consumes a start, update, enter, and leave function, that represents the state for those actions.
Inside you function as child function is where you define the animation. In our case, we want to translate the Box along its x axis, using the x value provided on the state object.
OBS: On my example the Box returns to the start (x === 0) when its offset value is bigger than the window's width.
I hope it helps.

React: Select body part from image

I want to build a website with React on which you can select different parts of a body. I would like to ask for your opinion what would be the best possibility for that? How can I highlight different parts of the body and make them clickable?
I would image a screen like this where I can press e.g. an arm, leg, head etc.:
Thank you for your help!
You will need two images.
Original colour body shape ( let's call this passive state ).
Active colour body shape.
Create a grid of rectangles on top of passive state image according to body parts, slice the active body shape image and put in rectangles as background images and set the image size to 0. On hover just set the size of the image to the original value.

Resources