My component within my modal is rendering twice

Asked

Viewed 188 times

0

I have a parent component that opens a modal based on the value of this variable:

const [openFullScreenModal, setOpenFullScreenModal] = useState(false)

I have a button in this component that arrow the value of this variable to true:

setOpenFullScreenModal(true)

In my template, I have a modal that opens when the value of this variable is true:

{ openFullScreenModal === true ? 
    <ModalFullScreen
        FormComponent={UsersFormPermissionsGroupPermissions}
        title="Permissões do grupo"
        onCloseModal={setOpenFullScreenModal}
        open={openFullScreenModal}
    />
    :
    <> </>
}

This is my Modalfullscreen Component:

const ModalFullScreen = (props) => {

    const { title, FormComponent, open, onCloseModal } = props
    const classes = modalFullScreenStyles()

    const handleClose = () => {
        onCloseModal(false)
    }

    return (
        <div>
            <Dialog fullScreen open={open} onClose={handleClose}>
                <AppBar className={classes.appBar}>
                    <Toolbar>
                        <Typography variant="h6" className={classes.title}>
                            {title}
                        </Typography>
                        <IconButton edge="start" color="inherit" onClick={handleClose} aria-label="fechar">
                            <Typography variant="h6" className={classes.title}>
                                Cancelar
                            </Typography>
                        </IconButton>
                    </Toolbar>
                </AppBar>

                <FormComponent></FormComponent>

            </Dialog>
        </div>
    )

In my UsersFormPermissionsGroupPermissions component I use a useEffect() to fetch data from an api:

useEffect(() => {
    console.log('mounted again')
    dispatch(groupPermissionsActions.getPermissionsGroupById(idGroupCompany))
})

I realized that my api was being called twice, so I put this console.log() and confirmed that my component is being re-rendered twice when I click on the button of my parent component to open that modal, my modal opens and the component I am passing to the modal is rendered twice.

'Cause this is happening?

  • 1

    When that UsersFormPermissionsGroupPermissions is created and then it automatically updates, the related component also updates, Maybe it is this and your rendering observation is very pertinent, as we do not have the total code gets complicated to say but, face I would like this, in the Father component of the two components I rescued the information and by propspassed to this other component so the Father is responsible for sending only information to the children.

  • 1

    It is not that it is rendering two must, it creates the component and then updates the component with the asynchronous process if it could already send the information to it before opening

  • @Virgilionovic actually, after I do the Dispatch he renders the component again. Can you provide an example of how I can pass a property to the component my modal will render? I tried something like: <Modalfullscreen Formcomponent={Usersformpermissionsgrouppermissions propriedadePassar="test"} but got "}" expected

  • 1

    @Virgilionovic I accidentally forgot to put the [] after the useEffect, so after any action he was rendering my component again. I could easily fix with: useEffect(() => { Dispatch(groupPermissionsActions.getPermissionsGroupById(idGroupCompany)) }, [])

1 answer

1


I’ll leave an example anyway, with the useEffect to render the component and after that update a local state variable to load the information thus not generating unnecessary rendering, example:

function Modal({onClose}) {
  const [data, setData] = React.useState({});
  const loadData = () => {
    fetch('https://viacep.com.br/ws/01001000/json/')
      .then(response => response.json())
      .then(response => setData(response));
  }  
  React.useEffect(() => {
    loadData();
  }, []);    
  return (
    <div>
      <h1>Modal</h1>
      <button onClick={onClose}>Close</button>
      <h3>Data</h3>
      <ul>
        { data && (<li>{data.cep}</li>) }
        { data && (<li>{data.localidade}</li>) }
        { data && (<li>{data.logradouro}</li>) }
      </ul>
    </div>
  )  
}

function Pai() {
  const [open, setOpen] = React.useState(false);  
  const onClose = () => { 
    setOpen(false);
  }
  const onOpen = () => {
    setOpen(true);
  }
  
  return (
    <div>
      {open && <Modal onClose={onClose}/>}
      {!open && (<button onClick={onOpen}>Open</button>)}
    </div>
  );
}
ReactDOM.render( <Pai/> , document.getElementById('root'));
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.9.0/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.9.0/umd/react-dom.production.min.js"></script>
<div id="root"></div>

  • Thank you for the layout, in my case, the call to the api should be made through the parent component and pass to the child by props or; be made in the child modal component because the modal in this project is only a "shell" and should not keep exclusive states of some component

  • In what I realized now can be done in the same child in my example, the effect was what you expected in creating a single rendering of the component ... @veroneseComS , although my comment was made on not seeing what you had done in the component, it is always good to put all the components the next time ... it was missing even the [] in useEffect meaning after creation run this function one time ...

  • 1

    Yes, my problem happened because I forgot to put the [] after the useEffect, when placing, rendered only once, even though the call of the api in the child.

Browser other questions tagged

You are not signed in. Login or sign up in order to post.