Почему этот компонент React отрисовывается дважды?

Проблема в том, что компонент визуализируется дважды, один раз с начальным состоянием, снова после метода setState в обещании axios. Почему это происходит и как я могу это решить.

Я использовал как componentWillMount, так и componentDidMount. Я, будучи новичком, очень старался и не мог понять почему.

export default class Dashboard extends Component{

  constructor(props) {
    super(props)
    this.state = {
      data: {
        okay: 'lul'
      }
    }
  }

  componentWillMount() {
    axios
      .get('/api/data?param1='+this.props.location.state.param1+'&param2='+this.props.location.state.param2)
      .then(res => {
        if (res.status != 401) {
          if (res.err)
            console.info('Error while retrieving: ', res.err)
          else {
            this.setState({
              data: res.data.data
            })
          }
        } else {
          console.info('Unauthorized!');
        }
      })
  }

  render() {
    return (
        <Segment inverted vertical>
          <CardContainer data = {this.state.data}/>
        </Segment>
    )
  }
}

Даже базовые предложения, связанные с реакцией / JS / общим программированием, высоко ценятся.

Как вы думаете, почему это проблема? Если вы не хотите ничего показывать до получения данных, вы можете проверить this.state.data в методе рендеринга и вернуть null, если данных для отображения еще нет. setState будет вызывать каждый раз метод render.

Håken Lid 02.05.2018 11:53

@ HåkenLid Предложенное вами решение работает отлично. Но как я могу визуализировать компонент только один раз с правильными данными? Должен ли я написать запрос axios внутри конструктора, а затем установить начальное состояние?

psvs 02.05.2018 12:13

Такое поведение и должно работать. Это не ошибка. Вызвать render действительно довольно дешево, так как response позаботится об обновлении dom эффективным образом. В некоторых случаях вы можете захотеть настроить, когда происходит повторная рендеринг. Это обсуждается в документации по реакции здесь: shouldComponentUpdate в действии

Håken Lid 02.05.2018 12:32
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Навигация по приложениям React: Исчерпывающее руководство по React Router
Навигация по приложениям React: Исчерпывающее руководство по React Router
React Router стала незаменимой библиотекой для создания одностраничных приложений с навигацией в React. В этой статье блога мы подробно рассмотрим...
Массив зависимостей в React
Массив зависимостей в React
Все о массиве Dependency и его связи с useEffect.
9
3
16 777
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

У вас есть асинхронный запрос в componentWillMount, поэтому до того, как запрос будет завершен, ваш компонент визуализируется, однако после успешного выполнения асинхронного запроса у вас есть вызов функции setState, который запускает повторную визуализацию, и, следовательно, ваш компонент визуализируется дважды

Это ожидаемое поведение.

Вы можете проверить этот вопрос для получения более подробной информации

Используйте функции жизненного цикла componentWillMount или componentDidMount для асинхронного запроса в React

Согласно документам

componentWillMount() вызывается непосредственно перед монтированием. Он вызывается перед render (), поэтому вызов setState() synchronously в этом методе не приведет к дополнительному рендерингу.

Это означает, что если вы напишете

componentWillMount() {
   this.setState({count: 1});
}

состояние будет отражено в самом начальном рендере, и рендеринг не будет запущен. Однако, если у вас есть асинхронный метод, вызов setState внутри него может вызвать дополнительный рендеринг, если асинхронный запрос будет завершен после того, как рендеринг уже вызван.

Чтобы подчеркнуть этот факт, вы не должны больше использовать componentWillMount, так как React предназначен для удаления этого метода из будущих крупных релизов. Вместо этого используйте componentDidMount.

Понял тебя. Итак, всякий раз, когда устанавливается состояние, вызывается метод рендеринга. Но они говорят, что реакция «интеллектуальная», не выполняет избыточный рендеринг. Что ты говоришь?

psvs 02.05.2018 12:18

React не выполняет избыточный рендеринг в dom, но по-прежнему вызывает метод рендеринга, именно здесь он выполняет виртуальное сравнение DOM и решает, рендерить или нет.

Shubham Khatri 02.05.2018 12:27

Было написано: «Вызов setState () в этом методе вызовет дополнительный рендеринг, но он гарантированно очистится во время того же тика. Это гарантирует, что даже если render () будет вызываться дважды в этом случае, пользователь не будет см. промежуточное состояние ». У меня есть только два экземпляра состояния: начальный и setState. Промежуточное состояние является начальным?

psvs 02.05.2018 12:28

синхронный вызов setState в componentWillMount не приведет к дополнительному рендерингу, но, поскольку здесь есть дополнительный асинхронный метод, он вызывает дополнительный повторный рендеринг

Shubham Khatri 02.05.2018 12:29

Другие вопросы по теме