Задать вопрос
VK_31
@VK_31
Постоянно учусь

Как отобразить сообщение при ошибке fetch?

Есть компонент, который выводит сообщения об ошибках
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>
        );
    }
}


Есть его провайдер
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>
    )
}


Все приложение обернуто в этот провайдер
function App() {
  const routes = useRoutes();
  return (
    <AlertProvider>
      <Router>
        <div className="App">
          <Nav />
          <Test />
          {routes}
        </div>
      </Router>
    </AlertProvider>
  );
}


Вот собственно компонент в котором по нажатии кнопки ошибка успешно отображается
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>
        </>
    )
}


Как добавить вызов функции до рендера? Сейчас выходит ошибка TypeError: Cannot read property 'addAlert' of undefined

И попутный вопрос: можно ли класс Snackbar перевести в функициональный компонент и есть ли другой способ сделать подобный компонент для отображения сообщений?
  • Вопрос задан
  • 189 просмотров
Подписаться 1 Простой Комментировать
Пригласить эксперта
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы