React. В setState новое значение сохраняется только при втором нажатии. При первом даёт предыдущее значение. Как можно исправить?

Делаю приложение по показу новостей, используя стороннее API. Положил в state базовую строку от которой зависит какие новости показать. При нажатии на ссылку срабатывает функцию, которая идёт по компонентам App => HeaderApp => NewsLinksItem. От последнего получаем новую категорию. Сама строка, если вывести в консоль выводится без проблем. Однако при записи в setState и просмотре через консоль, получается так, что запись происходит со второго раза и выводит предыдущую строку, которая была до новой.

Само поведение при нажатии можно увидеть в консоли: https://deokti.github.io/JavaScript/React/NewsAppR...

APP (Ссылка)
import React, { Component } from 'react';

import NewsLinks from '../news-links';
import SearchNewsButtons from '../search-news-buttons';
import NewsContent from '../news-content';

import '../gloval-style/style.scss';
import './App.scss';

export default class App extends Component {
  state = {
    category: 'general',
  }


  // componentDidUpdate = () => {
    
  // }

  onChangeCategory(category) {
    this.setState({category}, () => {
      this.getCategory()
    });
    console.log(this.state)
  }

  getCategory = () => this.state.category;

  render() {
    return (
      <React.Fragment>
        <header className='header'>
          <div className='container'>
            <div className="header__wrapper d-flex a-item-center">
              <h1 className="header-title"><a className="header-title-link" href="./index.html">НОВОСТИ</a></h1>

               {/* Навигация отдельно в item-list */}
               <nav className="nav m-auto">
                  <NewsLinks onChangeCategory={(name) => this.onChangeCategory(name)} />
               </nav>

              {/* Обрамляем часть секции для переноса в правую сторону */}
              <div className="detailed-container d-flex">
                <SearchNewsButtons />
              </div>
            </div>

          </div>
        </header>

        <section className="news">
          <div className="container">
            <NewsContent category={this.state.category} />
          </div>
        </section>
      </React.Fragment>
    )
  }
}


NewsLinks (Ссылка)
import React, { Component } from 'react';

import NewsLinksItem from '../news-links-item';

import './news-links.scss';

export default class NewsLinks extends Component {
  categoryLinks = [
    { name: 'general', label: 'Общие' },
    { name: 'sports', label: 'Спорт' },
    { name: 'entertainment', label: 'Развлечения' },
    { name: 'technology', label: 'Технологии' },
    { name: 'science', label: 'Наука' },
    { name: 'business', label: 'Бизнес' }
  ]

  
  render() {
    const { onChangeCategory } = this.props;

    const createButtons = this.categoryLinks.map(({name, label}) => {
      return (
        <li className="nav-item" key={name} onClick={() => onChangeCategory(name)}>
          <NewsLinksItem 
            name={name} 
            label={label} 
          />
        </li>
      )
    });

    return(
      <ul className="nav-list d-flex ul-none a-item-center">
        {createButtons}
      </ul>
    );
  }
}


NewsContent (В него передаётся состояние state из AppСсылка)
import React, { Component } from 'react';

import './news-links-list.scss';

export default class NewsLinksLinst extends Component {

  categoryLinks = [
    { name: 'general', label: 'Общие' },
    { name: 'sports', label: 'Спорт' },
    { name: 'entertainment', label: 'Развлечения' },
    { name: 'technology', label: 'Технологии' },
    { name: 'science', label: 'Наука' },
    { name: 'business', label: 'Бизнес' }
  ]

  fdsadsa = (event) => {
    event.preventDefault();
    this.props.onCategory(event.target.dataset.category);
  };


  
  render() {    
    const createButtons = this.categoryLinks.map(({name, label}) => {
      return (
        <li className="nav-item" key={name}>
          <a href={name} 
            data-category={name} 
            onClick={this.fdsadsa}
            className="nav-link">{label}</a>
        </li>
      );
    });

    return (
      <ul className="nav-list d-flex ul-none a-item-center">
         {createButtons}
      </ul>
    );
  }
};
  • Вопрос задан
  • 1252 просмотра
Решения вопроса 1
TchernyavskD
@TchernyavskD
Formoshlep
setState асинхронен, в документации это 3 абзац https://ru.reactjs.org/docs/react-component.html#s... Ты можешь удостовериться сделав в 2 параметре setState проверку с консоль логом, либо в самом рендере на то, что значение поменялось и еще несколько вариантов проверок
Ответ написан
Пригласить эксперта
Ваш ответ на вопрос

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

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