Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Whenever component re-renders, draggable item jumps down and to the right #84

Open
owenpriestley opened this issue Mar 10, 2021 · 2 comments

Comments

@owenpriestley
Copy link

I have a set of tags, which include locationX and locationY values. When my component renders, they appear in the right place. However, I want to be able to drag these to a new location, and then save that location.

Here is my code:

return Object.keys(tags).map(item => {
        if (tags[item] !== null) {
          var tagData = tags[item];
          tempLocation[item] = tagData;
          console.log(
            `Rendering item at: ${tagData.locationX} / ${tagData.locationY} (${tagData.item.attributes})`,
          );
          return (
            <Draggable
              x={tempLocation[item].locationX}
              y={tempLocation[item].locationY}
              onPressIn={e => {
                console.log(
                  `Current tempLocation = ${tempLocation[item].locationX} / ${tempLocation[item].locationY}`,
                );
              }}
              onDragRelease={(e, y, bounds) => {
                console.log(
                  `Releasing drag at ${e.nativeEvent.pageX}) / ${e.nativeEvent.pageY}`,
                );
                console.log(bounds);
                tempLocation[item].locationX = e.nativeEvent.pageX;
                tempLocation[item].locationY = e.nativeEvent.pageY;
                setCount(count + 1);
                // Updating state here makes the item jump downward and to the right. 
                // Removing setCount() fixes the issue.
              }}>
              <View
                key={item}
                style={{
                  position: 'absolute',
                }}>
                <View style={[styles.tagItemView]}>
                  <View
                    style={{
                      flex: 1,
                    }}>
                    <Text
                      style={[
                        typography.caption2,
                        {marginLeft: 3, marginRight: 25},
                      ]}>
                      {tags[item].item.attributes}
                    </Text>
                  </View>
                  <View style={{flex: 1, alignContent: 'flex-start'}}>
                    <Text
                      style={[
                        typography.footnote,
                        {marginLeft: 3, marginRight: 25},
                      ]}>
                      {tags[item].item.name}
                    </Text>
                  </View>
                </View>
              </View>
            </Draggable>
          );
        }
      });

For reference, here's setCount: const [count, setCount] = useState(0);

The parent view is simply a View with flex: 1

Eventually I'd like to replace this with a hook that updates the most recent location. Any kind of re-render seems to cause the jumping issue, whether it's through Redux props, hooks, or setState.

@phillipcmittmann
Copy link

phillipcmittmann commented Mar 11, 2021

I had the same problem, then I started to mess with his example and created a normal variable to store the position of the draggable. Probably is not the best solution, and I need to work on my project to test if this works there.

var initialY = initialPosition; // any value you want

...

<Draggable
      y={initialY}
      onDrag={(event, gestureState) => initialY = gestureState.moveY}
      /* other props you want */
/>

@owenpriestley
Copy link
Author

Awesome - thanks for sharing.

I also made some progress since posting this issue yesterday. I'm storing the X and Y coordinates for each view in Firebase, and when the component renders I use those as the initial X and Y props. I also made a copy of the item in the local component state using hooks.

Then, rather than updating initial props on drag, I just update the new copy in local state. Once the user chooses to save their changes, I send the local state copy back to Firebase. I think this will work, but needs further investigation.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants