Home > Back-end >  ReactJs clear state after modal close
ReactJs clear state after modal close

Time:05-04

I am working on a modal that fetch() some datas. When the modal closes and than reopen it visualize the old datas for some secs and than update the datas.

I want to avoid that the old datas being displayed, just empty field. The component is wrote in class way, I have a componentDidUpdate - where I do the fetch().

Any suggestions are welcome!

export class InfoCustomer extends React.Component {
constructor(props) {
    super(props);
    this.state = {
        clientInfos: {},
        clientCards: {},
        clientSubcsriptions: {},
    }
}

componentDidUpdate(prevProps) {
    if (this.props.show && !prevProps.show) this.openDetail();
}

openDetail() {

    WGet("Customers/preview", { id: this.props.customerId })
        .then(response => {
            this.setState({ clientInfos: response.data })
            //  API tessere
            WGet("Cards/customer", { customerId: this.props.customerId })
                .then(response => {
                    this.setState({ clientCards: response.data });
                    //  API Abbonamenti
                    WGet("Authorizations/customers/subscriptions", { customerId: this.props.customerId })
                        .then(response => this.setState({ clientSubscriptions: response.data }))
                        .catch((error) => {
                        });
                })
                .catch((error) => {
                });
        })
        .catch((error) => {
            this.setState({ hasError: true, messageError: error.responseMessages });
        });
}

And the return:

 return (
        <WModalOperation show={this.props.show} title={customerFullName} maxWidth="md"
            buttons={
                <WiButton variant="ghost" onClick={() => handleOnClose()}>Chiudi</WiButton>}>

            <Grid container  spacing={2} sx={{ height: '100%', overflow: 'hidden' }} >

                {/*Avatar and name*/}
                <Grid item xs={3} sx={{ display: 'grid', height: '100%', maxHeight: '100%', placeSelf: 'center', flexFlow: 'column ' }}>

                    <Grid sx={{ display: 'flex', alignItems: 'center' }}>
                        <WiInitialName size='big' photo={clientInfos.profilePictureUrl} alt={clientInfos.firstName} />
                    </Grid>

                    <Grid sx={{ display: 'flex', alignContent: 'center', flexFlow: 'column wrap', justifyContent: 'space-around', pl: 1, mt: 2 }}>
                        <Grid sx={{ mb: 3, display: 'flex', justifyContent: 'center' }}><WiLabel >{customerFullName}</WicLabel> </Grid>
                    </Grid>

                </Grid>


                {/*4 cards with leftBorder $bool*/}
                <Grid item xs={3} sx={{ display: 'flex', flexFlow: 'column wrap', height: '100%', alignItems: 'stretch', flexGrow: '1', gap: '1em', maxHeight: maXHeight }}>
                    {col1ToRender.map((item, i) => <CardContainer key={i} color={leftBorderColor(col1ToRenderParams[i].value)} title={item} content={col1ToRenderParams[i].name} />)}
                </Grid>
                {/*4 cards with leftBorder $bool*/}
                <Grid item xs={3} sx={{ display: 'flex', flexFlow: 'column wrap', height: '100%', alignItems: 'stretch', flexGrow: '1', gap: '1em', maxHeight: maXHeight }}>
                    {col2ToRender.map((item, i) => <CardContainer key={i   4} color={leftBorderColor(col2ToRenderParams[i].value)} title={item} content={col2ToRenderParams[i].name} />)}
                </Grid>
                {/*Customer packages*/}
                <Grid item xs={3} sx={{ display: 'flex', flexFlow: 'column ', height: '100%', maxHeight: '368px', overflowY: 'scroll', alignContent: 'center', mt: '16px' }}
                    style={hideScrollbar}                        >
                    {customePackages}
                </Grid>
            </Grid>
        </WiModalOperation>
    )
}

}

I have done this:

 const handleOnClose = () => {
        this.setState({
            clientCards: {},
            clientInfos: {},
            clientSubscriptions: {},
        })
        this.props.show = !this.props.show
    }

CodePudding user response:

Reset the state to empty

So assuming you're using the useState hook you can trigger another set state and empty the data.

Pseudo code example

const MyComp () => {
  const [state, setState] = React.useState({});
  React.useEffect(() => {
   /** query logic **/
   setState(data);
  }, [])

  const handleClose = () => {
    /** default close logic **/
    setState({}) // setting empty state on close
  }
  
  return (
    <Popup>
      <CloseButton onClickClose={() => handleClose()}>
    </Popup>
  )
}

CodePudding user response:

Rather than having the InfoCustomer component always rendered and shown/hidden from a prop, you could have the parent component conditionally render it.

Something like so:

const parentComp = () => {
   *component logic*

   return (
      <div>
         {this.state.show && <InfoCustomer/>} 
      </div>
   )
}

This way, when you close the modal, the component will be unmounted and the state will be cleared. You'll have to rework the InfoCustomer component to no longer use componentDidUpdate and instead use componentDidMount to perform your fetch.

  • Related