0

So I wanted to create a popup div that would slide from the side when an object has been selected and then exit when the object is re selected. I also want to create an exit button that would also close the div. I can pretty much understand how to do this except that I want to reuse this div component which is why I have kept it as an export in a different javascript file. This is where the issue is as I am having trouble handling the events across the files.

Here is my code:

/*Popup div export*/

export default () => {

  const [toggle, set] = useState(true);

  const { xyz } = useSpring({
      from: { xyz: [-1000, 0, 0] },

    xyz: toggle ? [0, 0, 0] : [-1000, 0, 0]
  });

  return (
    <a.div
      style={{
        transform: xyz.interpolate(
          (x, y, z) => `translate3d(${x}px, ${y}px, ${z}px)`
        )
      }}
      className="expand"
    >
      <Link to={link}>
        <a.button>Next</a.button>
      </Link>
      <button onClick={() => set(!toggle)}>Exit</button>
    </a.div>
  );
};


/*This is where I am implementing the export*/

      <Canvas>

        <Suspense fallback={<Fallback />}>

          <Cube position={[-1.2, 0, 0]} onClick={e => <Toggle />} /> <---/*Here is the click event where I call the div*/-->

          <Cube position={[1.2, 0, 0]} />
        </Suspense>
      </Canvas>

  );
}

I have tried changing the styling to make the display 'hidden' and 'block' but this doesn't work as it doesn't show the slide in animation it just pops up. Furthermore, If I try to manipulate this separately, for example, create a click event within the canvas to make the div appear with react-spring, if I try to use the exit button, the click event doesn't work anymore.

Here is my sandbox to show what is happening. : (p.s sorry if this all seems confusing) The codes are within Page1.js and toggle.js

https://codesandbox.io/s/sad-goldberg-pmb2y?file=/src/toggle.js:250-326

Edit: simpler sandbox visual: https://codesandbox.io/s/happy-chatelet-vkzjq?file=/src/page2.js

Sophia98
  • 339
  • 5
  • 17

1 Answers1

1

Your example is a bit confusing to follow, a simpler reproduction would be nice. That said, if I understand the overall goal, I think you want to store some global state (perhaps in your App.js component) that has some sort of state about the sidebar being visible.

For example:

function App() {
  const [sidebarVisible, setSidebarVisible] = React.useState(false)

  const toggleSidebar = () => setSidebarVisible(!sidebarVisible)

  return (
    <Router>
      <Switch>
        <Route path="/page1">
          <Page1 toggleSidebar={toggleSidebar} />
        </Route>
        <Route path="/page2">
          <Page2 toggleSidebar={toggleSidebar} />
        </Route>
        <Route path="/">
          <Start toggleSidebar={toggleSidebar} />
        </Route>
      </Switch>
    </Router>
  )
}

function Page1({ toggleSidebar }) {
  return <Toggle toggleSidebar={toggleSidebar} />
}

function Toggle({ toggleSidebar }) {
  return <button onClick={toggleSidebar}>Toggle</button>
}

This is just to give you ideas, you could of course pass the setSidebarVisible function or make another function that stores some sort of state about what should show on the sidebar.

You could also use something like Redux or React Context to pass down state/actions into your components.

Hope this helps somewhat

Dana Woodman
  • 4,148
  • 1
  • 38
  • 35
  • Thank you for your help Dana. Yes haha sorry about my confusing sandbox I will upload a simpler one. So looking at your solution, I don't understand how I would implement my toggle export and activate it. Here is the simplified sandbox if you want a better visual: https://codesandbox.io/s/happy-chatelet-vkzjq?file=/src/page2.js – Sophia98 Apr 20 '20 at 18:36
  • You just use a component and pass in the `toggleSidebar` method to it. You don't use a component as an event handler. I've updated code to hopefully be a bit clearer – Dana Woodman Apr 20 '20 at 20:31
  • Hi Dana, thank you again, I have tried to pass them down. In my page.js files I have included `onClick={toggleSidebar}` and have done the same with in the exit button found in my toggle export. From my animation I have also changed it to this `xyz: toggleSidebar ? [0, 0, 0] : [-1000, 0, 0]` and included the toggleSidebar instead of `active?` which used a local hook. However, it still hasn't worked and I don't know why. No errors occur however. – Sophia98 Apr 20 '20 at 21:10
  • "toggleSidebar" is a function so not sure why you're using it in a ternary expression? Maybe you mean to use something like "sidebarVisible" instead? – Dana Woodman Apr 20 '20 at 22:10
  • I don't know how to pass it down. Sorry about this but I am kind of confused by the arrangement. I haven't declared the component anywhere since If did as you have displayed it just appears and stays on the screen and I don't know how to pass the sidebarVisible since I am not declaring. Do you recommend I declare the component in the main app function? – Sophia98 Apr 20 '20 at 22:39
  • If I understand correctly, you want to store whether or not the sidebar is open in state at the top of your hierarchy, like in App.js. Then, you want to pass some function to your components so they can show the sidebar. Then the sidebar has a button a user can press to close it. Is that correct? – Dana Woodman Apr 20 '20 at 23:25
  • I have figured out how to do the animation by placing a div around the component and using react-spring within the app export. Anyways, thank you for the pointers and your patience, i know this was a little bit confusing – Sophia98 Apr 30 '20 at 21:53