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

Effectively resetting state data #120

Closed
JasonStoltz opened this issue Dec 22, 2020 · 4 comments
Closed

Effectively resetting state data #120

JasonStoltz opened this issue Dec 22, 2020 · 4 comments

Comments

@JasonStoltz
Copy link

I'm using a logic in a React component. This is a super simplified example:

const SomeComponent = ({ id }) => {
  const { record } = useValues(SomeLogic);
  const { fetchData } = useActions(SomeLogic);

  useEffect(() => {
    fetchData(id)
  }, [id]);

  return <div>{ record.id }</div>; 
}

Assume that fetchData is a listener that fetches a record and stores it in the record field.

And let's say this component is rendered with an id of 1. Data is fetched and the id of record 1 has been rendered.

The id prop then changes to 2. fetchData is called and then the id of record 2 is rendered.

However, on that second render, just after the id prop changes to 2, there is a brief period where the id prop is 2, but the record is still the old record, which is record 1. And it stays that way until fetchData completes and the current record is updated.

I'm trying to avoid that.

What I'd really like to happen, is when id changes, I'd like to the logic to be completely reset. How can I accomplish that?

A couple of thoughts I've had:

  1. Add a key to SomeComponent, so like <SomeComponent key={id} id={id} /> which should cause SomeComponent to remount, which I was hoping would also cause the logic to remount as well... but that doesn't seem work. SomeLogic still doesn't seem to be remounted.
  2. Add a key to the logic store, so like useValue(SomeLogic({ id }). Which I think would work ... but the problem I find there which is not apparent in this example ... is in all the nested components where I want to access SomeLogic.record, I always need to pass that key, so I end up passing that key all around my code which is not ideal.

Is there some way to force that logic to remount?

Any insight would be appreciated.

Thanks!

@JasonStoltz
Copy link
Author

After I think about this more, I think the key thing I'm missing, is the fact that I cannot force a component that uses useValues or useActions to re-mount alongside the consuming component using a key prop.

This is something I often do with routing. I.e.,

    // for route /something/{id}
    const { id } = useParams() as { id: string };
    //...
    <SomeComponent key={id} id={id} />

If the user navigates between these two routes:

  1. /something/1
  2. /something/2

The matching route of /something/{id} doesn't change. The only thing that changes is theid. Because of this, I use key={id} to force a re-render of SomeComponent.

So what I'm saying, is it would be great if when SomeComponent remounts, that SomeLogic would remount as well.

Does that make sense?

@mariusandra
Copy link
Member

Hey @JasonStoltz , the right answer to cleanly separate the data of the two records is to use a key like you wrote in point 2 in your original post... and that means calling useValues(SomeLogic({ id })) all the time.

I just finished a draft PR that lets you use one specific keyed logic without passing the props down a component chain. This is done with React Context. I wrote a draft blog post about the feature as well.

I'd be very curious to hear if that can solve your usecase.

Apologies for the long delay in my reply though :)

@JasonStoltz
Copy link
Author

@mariusandra Oh wow, this is a great solution. Thanks for the follow up!

@mariusandra
Copy link
Member

So this is now live in kea 2.3 as a <BindLogic/> component.

I'm also very curious to hear if this solved the original problem or not.

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