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

Bug: Method from React Context can't read its own state. #22549

Closed
eakl opened this issue Oct 13, 2021 · 2 comments
Closed

Bug: Method from React Context can't read its own state. #22549

eakl opened this issue Oct 13, 2021 · 2 comments
Labels
Status: Unconfirmed A potential issue that we haven't yet confirmed as a bug

Comments

@eakl
Copy link

eakl commented Oct 13, 2021

React version: 17.0.2

Steps To Reproduce

  1. Open the Code Sandbox and the Console
  2. Click on Open. You will see the following console.logs (1. the modal opens, 2. the config input that is passed contains data and 2 callbacks, 3. the config is set in the state)
  3. Close the modal with the X button or with Cancel (you will see the following console.logs (1. the modal closes, 2. the dialogConfig state is empty)
  4. Reproduce steps 1 to 4, you will see that the dialogConfig state is not empty.
  5. Open the React Dev Tools and click on Context.Provider to see that the dialogConfig object is always updated when the modal opens but not always cleared when the modal closes

Here is the code sandbox with different modal dependencies but same issue:

The current behavior

When onOpenDialog is called, the dialogConfig state is updated every time but onCloseDialog see it as empty half the time and the condition doesn't pass

const onCloseDialog = () => {
    console.log("-- Close Dialog");
    setDialogMode("");
    console.log("-- dialogConfig State: ", dialogConfig); // This is empty half the time
    if (Object.keys(dialogConfig).length > 0) {
      console.log("-- Reset dialogConfig");
      setDialogConfig({});
    }
  };

The expected behavior

When onCloseDialog is called, it should always read the state as non empty object

@eakl eakl added the Status: Unconfirmed A potential issue that we haven't yet confirmed as a bug label Oct 13, 2021
@ChamsBouzaiene
Copy link

ChamsBouzaiene commented Oct 13, 2021

@eakl first of all this is not a react bug it's a common problem that us devs stumble upon some time the issue here is with the function closures you are accessing dialogConfig state in the onCloseDialog your code assume that the function setDialogConfig is sync and also that the function is in the right scope but it's not it's bound to the previous closure when the function was created so to mitgate this issue when you have trouble with your function closure you can access your state like this :

 const onCloseDialog = () => {
    console.log("-- Close Dialog");
    setDialogMode(false);
    console.log("-- dialogConfig State: ", dialogConfig, dialogMode);
    setDialogConfig((prevConfig) => {
      if (Object.keys(prevConfig).length > 0) {
        console.log("-- Reset dialogConfig");
        return {};
      }
    });
  };

using the setDialogConfig callback you are sure that you are accessing the right state object without worring about the closures

another thing i would recommend that you drop the way you are passing the onCloseDialog and onSubmit function callbacks to the dialogConfig cause in that way you are adding an unnecessary step by adding function callbacks to state that are accessible via the context already instead directly pass them to the modal the consumer

I also invite you to read this article from dan about react hooks and closures
check demo here

@eakl
Copy link
Author

eakl commented Oct 14, 2021

@ChamsBouzaiene Thank you for the clear explanation and the reading material. I didn't know this was a known problem but it makes sense. I also appreciate your recommendation to simplify my code.

@eakl eakl closed this as completed Oct 14, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Status: Unconfirmed A potential issue that we haven't yet confirmed as a bug
Projects
None yet
Development

No branches or pull requests

2 participants