Eliav2 / react-xarrows

Draw arrows (or lines) between components in React!
https://codesandbox.io/embed/github/Eliav2/react-xarrows/tree/master/examples?fontsize=14&hidenavigation=1&theme=dark
MIT License
584 stars 75 forks source link

Drawing arrows on elements rendered via map() #83

Closed logankfuller closed 3 years ago

logankfuller commented 3 years ago

Hey,

I've been using this library for a while and I've been trying to use it to draw arrows between elements that are rendered via a .map() function. I'm stumped with getting it to work properly for me. I'm getting a dataset that I map() over and render. I'm currently giving each rendered element a dynamic ID based off of a sequence provided by the dataset as well as the .map() index.

I'm getting this result (with the IDs written in black):

alt text

When I force a re-render on the component, it renders correctly:

alt text

Now I know you can use the useXarrow() hook to ask the arrows to re-render, but I don't have a child component to place the hook in since I don't have any sort of event that I want them to re-render on. I just need them to render properly every time the component displays.

Anyone have any ideas on what I could do to achieve my goal?

  const { exercises, confirmSwap } = props;

  return (
    <IonGrid>
      <div className="ion-margin-bottom ion-margin-start">
        {exercises.map((exercise, index) => {
          if (index + 1 < exercises.length) {
            return (
              <>
                <IonRow key={index}>
                  <IonCol>
                    <div id={exercise.sequence[0] + index.toString()}>
                      <WorkoutDiv
                        showSwap
                        showInfo
                        data={exercise}
                        confirmSwap={confirmSwap}
                      />
                    </div>
                  </IonCol>
                </IonRow>
                <Xwrapper>
                  <Xarrow
                    zIndex={-1}
                    key={index}
                    start={exercise.sequence[0] + index.toString()}
                    end={exercise.sequence[0] + (index + 1).toString()}
                    startAnchor="left"
                    endAnchor="left"
                    showHead={false}
                    _cpx1Offset={-15}
                    _cpx2Offset={-15}
                    path="grid"
                    strokeWidth={2}
                    lineColor="#FFA300"
                  />
                </Xwrapper>
              </>
            );
          } else {
            return (
              <IonRow key={index}>
                <IonCol>
                  <div id={exercise.sequence[0] + index.toString()}>
                    <WorkoutDiv
                      showSwap
                      showInfo
                      data={exercise}
                      confirmSwap={confirmSwap}
                    />
                  </div>
                </IonCol>
              </IonRow>
            );
          }
        })}
      </div>
    </IonGrid>
  );
Eliav2 commented 3 years ago

please provide mininal working code-sandbox

logankfuller commented 3 years ago

I'm having trouble reproducing the issue code in CodeSandbox. I can only reproduce the issues in my project. The code is essentially what is in the following CodeSandbox though:

https://codesandbox.io/s/rendering-xarrows-ypuvd?file=/src/App.js

When I navigate away from the Route in my project and navigate back, the arrows are rendering incorrectly (as seen in the image in the original post). In the CodeSandbox, the arrows continue to render properly. The divs appear to be holding on to their refs and the console.log() in the CodeSandbox on line 29 in Home.js is showing the correct divs, but the arrows just aren't rendering properly. I'm fairly sure it's an issue in my project code that's causing it more than your package, but I'm just not sure what it could be.

Feel free to close this issue if you wish since I'm unable to really provide anything useful at this point in time.

Eliav2 commented 3 years ago

This might be an actual bug in react-xarrows, so I would like to invistigate it. I think this might be related to the multiple Xwrapper instances.

Please upgrade to v2.0.1, I manage these instances differently there. If the issue persists, please try to reproduce minimal example that reproduce that behavior. If you can't, you can upload your entire src folder to code sandbox, and share it (possible privately) with me

logankfuller commented 3 years ago

Hi,

Sorry for the long wait -- I've been working on reproducing the bug on my end and I think I finally have an idea what's causing it. I believe it's due to my project using the Ionic Framework for UI.

If I remove all of the <Ion*> (Ionic) tags from my project (at least as many as I can), the arrows work great.

I have a CodeSandbox with all the Ionic tags removed except for the ones absolutely required for a project and I get the same error I'm getting in my project. This leads me to believe that it's something to do with the Ionic router... I might try updating all of my dependencies and see if that helps.

https://codesandbox.io/s/react-xarrows-ionic-problem-gijb3

Click the Workout tab and you'll see the problem. If you resize the project area, it fixes itself.

I'd appreciate if you could take a look and provide your thoughts.

Eliav2 commented 3 years ago

Sorry, don't know this framework. This is not bug related, but you can open a discussion and ask there.