skip to Main Content

I’ve got a state to show a dialog inside a React

const [isConfirmationDialogVisible, setConfirmationDialogVisibility] = useState(false);

I set the visibility state when a button is clicked:

<Button id={item.id} 
            onPressCallback={() => setConfirmationDialogVisibility(true)} />

The visibility state is passed on to the dialog like this (isOwnItem is true):

<> ...
        {isOwnItem && <Dialog
            id={item.content.id}
            visible={isConfirmationDialogVisible}
        />}
</>

The visibility property is set inside the dialog from the dialog properties:

const [isVisible, setVisibility] = useState(props.visible);

and is passed on to an alert like this:

<StyledAlert show={isVisible} ... />

The alert has worked before, so I think the problem is not there.

Now, when I click the button, nothing happens. Help would be greatly appreciated!

2

Answers


  1. Chosen as BEST ANSWER

    I added a console output to the onPressCallback of the button and realised that isVisible was always false when the button was pressed.

    I have solved it now by adding the isVisible condition to the part where I call the dialog:

    {isOwnItem && isConfirmationDialogVisible && <Dialog
        id={item.content.id}
        visible={isConfirmationDialogVisible}
    />}
    

  2. By setting it into state (with useState), the value for props.visible will be set only on mount. It’s an inital value, it won’t be updated by props.visible changing; it will only update when setVisibility is called.

    When Dialog mounts, it will get the correct value, but new value set by setConfirmationDialogVisibility won’t update the value of isVisible

    If you need to change the state from inside Dialog, pass the state setter:

    <> ...
            {isOwnItem && <Dialog
                id={item.content.id}
                visible={isConfirmationDialogVisible}
                setVisible={setConfirmationDialogVisibility}
            />}
    </>
    

    If not, you could simply do away with setting the inner state:

    // not needed
    // const [isVisible, setVisibility] = useState(props.visible);
    
    <StyledAlert show={props.visible} ... />
    
    

    If you really must keep the inner state, AND you don’t want to pass the parent state setter, then you need a useEffect that updates the inner state when the outer state changes:

    const [isVisible, setVisibility] = useState(props.visible);
    
    useEffect(() => {
      setVisibility(props.visible)
    }, [props.visible])
    

    NOTE: I would not recommend this last method as there is a lot of redundant code

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search