'Toasty does not autoclose or manual close after hook list

I modified the code to generate a toast stack into a ToastContainer dynamically as a notification system. Now the toast do not autoclose even in close button click.

The code can be reproduced by copy and past inside of dimiss area in https://react-bootstrap.github.io/components/toasts/

const Tsty = (props) => 
    <>
    <Toast show={ props.show } delay={ 3000 } autohide>
      <Toast.Header>
        <img src="holder.js/20x20?text=%20" className="rounded me-2" alt="" />
        <strong className="me-auto">{props.title}</strong>
        <small className="text-muted">{props.time}</small>
      </Toast.Header>
      <Toast.Body>{props.body}</Toast.Body>
    </Toast>
    </>
render(<Tsty />);

function Example() {
  const [listNtfy, setNtfy] = useState([]);
  const style = { position: 'fixed', bottom: '60px', right: '10px', zIndex: '1000'}
  return (
    <>
    <Button onClick={() => {setNtfy([...listNtfy, {title: 'title #', time: 'now', body:  new Date().toString(), show : true }])}}>Add Ntfy</Button>
    <ToastContainer style={style}>
      { listNtfy.map( (x,i) => <Tsty show={ x.show } title={x.title + i} time={x.time} body={x.body} key={i} /> ) }
    </ToastContainer>
    </>
  );
}

render(<Example />);

where is the error?



Solution 1:[1]

This doesn't close cause Tosty hook to show property that is not present in the hook. To solve it, you can define the show property and create a function to hide it. When all ntfys are closed, the list is cleaned.

const Tsty = (props) => 
    <>
    <Toast show={ props.show } onClose={ () => {props.fcn(props.idx) } } delay={ 5000 } autohide>
      <Toast.Header>
        <img src="holder.js/20x20?text=Q" className="rounded me-2" alt="" />
        <strong className="me-auto">{props.title}</strong>
        <small className="text-muted">{props.time}</small>
      </Toast.Header>
      <Toast.Body>{props.body}</Toast.Body>
    </Toast>
    </>
render(<Tsty />);

function Example() {
  const [listNtfy, setNtfy] = useState([]);
  // Function to autohide the ntfys
  const autoHide = (key) => { 
    // Set visibility of Ntfy to hidden
    listNtfy.filter((x,i) => i === key)[0].show = false;
    // Apply the change
    setNtfy([...listNtfy]);
    // Check all notifications is hide (if yes, reset the list)
    if (listNtfy.every(v => v.show === false))
      setNtfy([]);
    };
  const style = { position: 'fixed', bottom: '60px', right: '10px', zIndex: '1000'}
  return (
    <>
    <Button onClick={() => {setNtfy([...listNtfy, { title: 'title #' + listNtfy.length, time: 'now', body:  new Date().toString(), show : true }])}}>Add Ntfy</Button>
    <ToastContainer style={style}>
      { listNtfy.map( (x,i) => <Tsty show={ x.show } title={x.title} time={x.time} body={ x.body } key={i} idx={i} fcn={ autoHide } /> )}
    </ToastContainer>
    </>
  );
}

render(<Example />);

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 Mingut