Coder Social home page Coder Social logo

Comments (5)

gilbarbara avatar gilbarbara commented on June 9, 2024

Hey @mtr1990

Setting the callback data in a state is an anti-pattern since the callback receives all the lifecycle events before the beacon or tooltip is rendered, which probably creates a race condition and breaks the functionality.
The callback changes significantly, and saving its data in a state will force the component to re-render like crazy.

Adding a "next tick" setTimeout to the state setter inside the callback handler proves that it is, in fact, a race condition.

setTimeout(() => {
	setCallbackData(data);
}, 0);
// This "works", but it's a huge red flag.

If you need to access the data outside the callback, I'd recommend saving it to a mutable ref instead.

function App() {
	const joyrideState = useRef<CallBackProps | undefined>();

	const handleJoyrideCallback = (data: CallBackProps) => {
		joyrideState.current = data;
	}
	...
	console.log('joyrideState', joyrideState.current);
}

from react-joyride.

mtr1990 avatar mtr1990 commented on June 9, 2024

Hi @gilbarbara ,

Thank you for your response.I tried your way but the status always returns undefined for joyrideState.current and helpers.current

https://codesandbox.io/p/sandbox/frosty-wozniak-w7sltw?file=%2Fapp%2Fpage.tsx%3A62%2C15

from react-joyride.

gilbarbara avatar gilbarbara commented on June 9, 2024

Hey @mtr1990

The initial logs will be undefined because the refs weren't set yet. And changing a ref doesn't re-render the component.
The Joyride component won't re-render the parent when it changes its internal state.

The example is too simple.
Try adding this to see the logs:

useEffect(() => {
  setTimeout(() => {
    console.log("joyrideState", joyrideState.current);

    console.log("helpers", helpers.current);
  }, 1000);
}, []);

What are you trying to achieve? Have you tried it in your real-life project?
If you try to use the helpers or the joyrideState in other methods, they will be available in the ref...

Anyway, this is not a problem with the library itself, just the implementation.
So, good luck!

from react-joyride.

mtr1990 avatar mtr1990 commented on June 9, 2024

Hi @gilbarbara

I am using in my real project. My desired goal is to access properties outside the callback.

But so far I have not achieved this despite trying many ways

Example: https://docs.react-joyride.com/callback

{
  action: 'start',
  controlled: true,
  index: 0,
  lifecycle: 'init',
  size: 4,
  status: 'running',
  step: { the.current.step },
  type: 'tour:start',
}

When I access inside the callback everything works fine in vite.js. But on next.js it doesn't work as expected

  const [run, setRun] = useState(true);

  const [callbackData, setCallbackData] = useState();

  const handleJoyrideCallback = (data: CallBackProps) => {
    const { status } = data;
    const finishedStatuses: string[] = [STATUS.FINISHED, STATUS.SKIPPED];

    if (finishedStatuses.includes(status)) {
      setRun(false);
    }

    setCallbackData(data); // => vite.js version works fine but next.js doesn't
                                           
  };

I also updated the example using outside callback with refs but returns undefined.

Can you help based on codesanbox?
https://codesandbox.io/p/sandbox/frosty-wozniak-w7sltw?file=%2Fapp%2Fpage.tsx%3A50%2C23

from react-joyride.

gilbarbara avatar gilbarbara commented on June 9, 2024

You can't set the callback data in a state. That is an anti-pattern that forces the parent component to re-render dozens of times without needing and creates a race condition that breaks the internal state of the Joyride component...
The vite version isn't working fine, it's just hiding the problem, and next.js isn't so forgiving.

Can't you call a method inside the callback when the state matches your condition? Why do you need the joyride state outside the callback?
Did you check the other examples in the demo? The Controlled one has quite complex logic inside the callback.

from react-joyride.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.