Реагировать на setState() после получения без повторного рендеринга

У меня данные получение в компонентDidMount()(Я получаю их в той форме, которую хочу), и я хочу сохранить их в состояние компонента с это.setState. Состояние не меняется.

  • Я консольный журнал, что я добираюсь до точки, где вызывается setState - есть условия
  • Я пробовал const that = this

Компонент не перерисовывается, и состояние не меняется, и я хотел бы знать, почему.

Мой код:

export class Offers extends Component {
    constructor(props) {
        super(props);
        this.renderOffer = this.renderOffer.bind(this);
        this.state = {
        ...
        };
    }
    componentWillMount() {
        this.setState(() => ({
            offer: {},
            isLoading: true,
            isMyOffer: false,

            ...
        }));
    }

    componentDidMount() {
        console.info('MOUNTED');
        const { profile } = this.props;
        if (profile) {
            this.setState(() => ({
                isLoading: false
            }));
        }
        if (profile && profile._id) {
            this.setState(() => ({
                isMyOffer: true,
                ...
            }));

            fetch(`/api/offers-by/${profile._id}`,{
                method: 'GET'
            })
           .then(response => response.json())
           .then(offers => {
               if (!offers || !offers.length) {
                   this.setState(() => ({
                   isLoading: false
                  })
                  );
              } else {
                  console.info('ELSE', offers[0]._id); // getting proper data
                  console.info('THIS', this) // getting this object 
                  const offerData = offers[0]
                  this.setState(() => ({
                      offer: offerData,
                      isLoading: false
                  })) //  then
              }}) // fetch
              console.info('STATE', this.state)
          }
          console.info('STATE', this.state)
    }

Пробовали ли вы вызывать setState передачу объекта вместо функции?

josepdecid 21.02.2019 11:15

Я этого не сделал, и, согласно исходному коду реакции, это не должно иметь значения.

Talita 21.02.2019 11:19

Откуда вы знаете, что состояние не меняется? Если ваша попытка отладки осуществляется через console.info(this.state), то ваша отладка неверна. fetch является асинхронным, поэтому состояние еще не изменится (оно произойдет после завершения выборки и выполнения then*). Но даже если вы снова зарегистрируете состояние в методе then, это не сработает, потому что setState также является асинхронным. Используйте обратный вызов setState, чтобы войти в журнал и посмотреть, изменилось ли состояние.

Gabriele Petrioli 21.02.2019 11:29

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

Talita 21.02.2019 11:41

@AgataAndrzejewska, опубликованный вами код не должен демонстрировать описанную вами проблему (если достигнуты логи ELSE и THIS). Вы уверены, что нет других частей вашего кода, которые могут мешать настройке состояния? Любые консольные ошибки/предупреждения? Можете ли вы опубликовать весь код компонента (и, возможно, также живую версию этого?)

Gabriele Petrioli 21.02.2019 11:48

@GabrielePetrioli Спасибо за помощь, на код действительно повлияли ошибки, возникающие при монтировании компонента. Таким образом, выборка работала, но setState не работал с размонтированным компонентом. Спасибо!

Talita 21.02.2019 12:31
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
В настоящее время производительность загрузки веб-сайта имеет решающее значение не только для удобства пользователей, но и для ранжирования в...
Безумие обратных вызовов в javascript [JS]
Безумие обратных вызовов в javascript [JS]
Здравствуйте! Юный падаван 🚀. Присоединяйся ко мне, чтобы разобраться в одной из самых запутанных концепций, когда вы начинаете изучать мир...
Система управления парковками с использованием HTML, CSS и JavaScript
Система управления парковками с использованием HTML, CSS и JavaScript
Веб-сайт по управлению парковками был создан с использованием HTML, CSS и JavaScript. Это простой сайт, ничего вычурного. Основная цель -...
JavaScript Вопросы с множественным выбором и ответы
JavaScript Вопросы с множественным выбором и ответы
Если вы ищете платформу, которая предоставляет вам бесплатный тест JavaScript MCQ (Multiple Choice Questions With Answers) для оценки ваших знаний,...
0
6
1 383
1

Ответы 1

setState имеет метод обратного вызова в качестве второго аргумента. Вы должны использовать его после начального setState. Это работает, потому что сам setState является асинхронной операцией. Метод setState() не сразу обновляет состояние компонента, а скорее, если есть несколько setStates , они будут объединены в один вызов setState.

this.setState(() => ({
            isLoading: false
        }),() =>{
   /// You can call setState again here and again use callback and  call fetch and invoke setState again..
});

В идеале вы могли бы преобразовать некоторые из ваших setStates в один вызов setState. Начните с пустого объекта и добавьте свойства к вашему объекту на основе условий.

const updatedState  = {}
if (loading){
 updatedState.loading = false
}
if (profile &&..){
 updatedState.someProperty = value.
}

this.setState(updatedObject,()=> {//code for fetch..
}) // Using the object form since you don't seem to be in need of previous State.

Спасибо за ответ! Ваши советы помогли мне найти решение.

Talita 21.02.2019 12:34

Круто, рад помочь

anuragb26 21.02.2019 12:35

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