Рендеринг одного и того же компонента в блоке try и catch в React без потери фокуса полей в ReactJS - PullRequest
0 голосов
/ 28 июня 2018

Я использую определенный компонент в ReactJS, который иногда может выдавать некоторые ошибки, поэтому мне нужно обернуть его блоком try-catch. Моя проблема заключается в том, что, когда он выдает ошибку, мне все еще нужно, чтобы компонент отображался и отображал ошибку пользователю, поэтому я передаю ошибку компоненту как prop, если он выдается. Посмотрите на этот пример кода:

myComponent = (error, data) => { /*render component/*}

renderComponent = () => {
     try { 
           /*THE CODE WHICH MAY THROW ERRORS
           BUT MAY ALSO RECEIVE DATA WITHOUT PROBLEM*/

           return this.myComponent(undefined,data); //if everything is fine
         } catch (e) {
           return this.myComponent(e,undefined);
         }
render {
   return ({this.renderComponent()});
}

С этой структурой все в порядке, за исключением одного факта: каждый раз, когда происходят некоторые ошибки, весь компонент сбрасывается, что логично, потому что мы визуализируем целый другой компонент (хотя он выглядит одинаково), но он теряет фокус текста поля и прокрутки снова и так далее.

Я попытался поставить data и error как state, чтобы они все были там установлены внутри renderComponent, и я позвоню myComponent отдельно и передам состояние, но в любом случае у меня было использовать setState внутри render, так что это вызывает проблемы, как вы знаете.

Так что я подумал спросить вас, что вы думаете об этом деле. Я не знаю о некоторых возможностях React?

Спасибо

1 Ответ

0 голосов
/ 28 июня 2018

Начиная с React 16, существует новый жизненный цикл компонента, называемый componentDidCatch, который в основном представляет собой попытку для компонентов.

В этом жизненном цикле вы можете отлавливать ошибки для определенных компонентов, поэтому только целое поддерево компонентов будет повреждено, а не все приложение, и вы сможете отображать различный контент в зависимости от состояния.

Подробнее об этом можно прочитать здесь .

В вашем случае вы можете сделать что-то вроде:

class TryCatchComponent extends React.Component {
  constructor(props) {
    super(props);

    this.state = { hasError: false, error: undefined, errorInfo: undefined };
  }

  componentDidCatch(error, errorInfo) {
    this.setState({ hasError: true, error, errorInfo });
  }

  render() {
    const { hasError, ...errorProps } = this.state;

    if (hasError) {
      const { fallback: FallbackComponent } = this.props;

      return <FallbackComponent {...errorProps} />;
    }

    return this.props.children;
  }
}

const SomeErrorDisplayComponent = ({ error, errorInfo }) => (
  <div>{error} or {errorInfo}</div>
);

const SomeComponent = () => (
  <TryCatchComponent fallback={SomeErrorDisplayComponent}>
    <ComponentThatMightCrashSometime />
  </TryCatchComponent>
);
...