M
M
Mikhail2020-01-29 16:18:02
React
Mikhail, 2020-01-29 16:18:02

How to display a message on fetch error?

There is a component that displays error messages

export class Snackbar extends React.Component {

    constructor(props) {
        super(props);
    }

    state = {
        messages: []
    }

    addAlert(message, timeout = null) {
        const uniqueId = Date.now();

        this.setState({
            messages: [{message, id: uniqueId, onClose: !timeout && this.closeAlert.bind(this)}].concat(this.state.messages)
        }, () => {
            if (timeout) {
                setTimeout(() => {
                    this.setState({
                        messages: this.state.messages.filter( m => m.id !== uniqueId)
                    });
                }, timeout);
            }            
        });
        
    }

    closeAlert(id) {
        this.setState({
            messages: [...this.state.messages.filter(m => m.id !== id)]
        })
    }

    render() {
        return (
            <div className="toast-container">
                <div className="toast">
                    {this.state.messages && this.state.messages.map( m => <Alert key={m.id} alert={m} />)}
                </div>
            </div>
        );
    }
}


Has a provider
import {Snackbar} from './Snackbar';

import AlertContext from './AlertContext';

export const AlertProvider = ({children}) => {

    const snackbarRef = useRef();

    const showAlert = (message = 'Button Pressed...') => {
        snackbarRef.current.addAlert(message, 3000);
    }

    return (        
        <AlertContext.Provider value={{showAlert}}>
            <Snackbar ref={snackbarRef} />
            {children}
        </AlertContext.Provider>
    )
}


The whole application is wrapped in this provider
function App() {
  const routes = useRoutes();
  return (
    <AlertProvider>
      <Router>
        <div className="App">
          <Nav />
          <Test />
          {routes}
        </div>
      </Router>
    </AlertProvider>
  );
}


Here is the actual component in which, on clicking the button, the error is successfully displayed
export const Test = () => {

    const {loading, request, error} = useHttp();
    const [orders, setOrders] = useState(null);

    const {showAlert} = useContext(AlertContext); //этот showAlert работает только в рендере

   showAlert('error'); //в этом месте ошибка

    useEffect( () => {
        async function getOrder() {
            try {
                const data = await request(`/api/parser/`, 'GET');
                setOrders(data);
            } catch (e) {
                //Вот в этом месте необходимо отобразить ошибку функцией showAlert
            }
        }
        getOrder();
    }, [request])

    return (
        <>
            <button onClick={() => showAlert('Test alert useContext')}>Show test alert useContext</button>
            <AlertContext.Consumer>
                {({ showAlert }) => (
                    <button onClick={() => showAlert('Test alert')}>Show test alert</button>
                )}
            </AlertContext.Consumer>
        </>
    )
}


How to add a function call before render? Now there is an error TypeError: Cannot read property 'addAlert' of undefined

And a related question: can the Snackbar class be translated into a functional component and is there another way to make a similar component to display messages?

Answer the question

In order to leave comments, you need to log in

Didn't find what you were looking for?

Ask your question

Ask a Question

731 491 924 answers to any question