React: как избежать вызова нескольких функций

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

Полный код компонента

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

    this.state = {
      Item: 5,
      skip: 0
    }

    this.handleClick = this.handleClick.bind(this);
  }

  urlParams() {
    return `http://localhost:3001/meetups?filter[limit]=${(this.state.Item)}&&filter[skip]=${this.state.skip}`
  }

  handleClick() {
    this.setState({skip: this.state.skip + 1})
  }

  render() {
    return (
      <div>
        <a href = {this.urlParams()}>Example link</a>
        <pre>{this.urlParams()}</pre>
        <button onClick = {this.handleClick}>Change link</button>
      </div>
    )
  }
}


ReactDOM.render(<Example/>, document.querySelector('div#my-example' ))
Поведение ключевого слова "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) для оценки ваших знаний,...
1
0
2 138
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

Там довольно много кода и нет рабочего примера, поэтому я могу ошибаться, но я думаю, что проблема в getSortedData(): в этой функции вы вызываете setState() и сразу после этого вызываете getData(), которая выполняет выборку, которая использует функцию ulrParams(), которая использует свойство this.state.sortedData.

Проблема в том, что setState() является асинхронным, поэтому нельзя быть уверенным, что когда urlParams() использует this.state.sortedData, свойство обновляется (на самом деле мы уверены, что оно не обновляется).

Попробуйте переписать getSortedData() следующим образом:

getSortedData =() => {
    this.setState({sortedData:'name desc'}, () => {
        this.getData();
    })
}

Здесь я передаю обратный вызов setState(): таким образом getData() будет вызываться ПОСЛЕ того, как вы обновите состояние.


Что касается вопроса, который вы задали в комментарии, если вы хотите переключить порядок, вы можете добавить свойство order в состояние Компонента, присвоив ему значение по умолчанию 'name desc'.
Затем вы меняете getSortedData следующим образом:

getSortedData =() => {
    let newSort = 'name asc';
    if (this.state.sorteData === newSort) 'name desc';

    this.setState({sortedData: newSort}, () => {
        this.getData();
    })
}
Ответ принят как подходящий

Состояние не updating во время вызова urlParams. Как @jolly сказал вам, что setState - это функция асинхронный, поэтому лучше использовать ее в callback, или вы можете просто передать свой тип отсортированные данные в качестве аргумента в функцию getSortedType вместо обновления состояния. Кроме того, сообщество ReactJS предлагает или лучше всего использовать state только в том случае, если props необходимо, чтобы быть updated.

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

getSortedData=()=>{
    this.setState({sortedData:'name desc'});
    setTimeout(() => {
      this.getData();
    }, 200);
}

Спасибо, работает!! . На самом деле я хочу большего, я хочу сделать логику, если пользователь нажимает первый раз, я хочу обновить его с помощью name asc, когда пользователь нажимает второй раз, я хочу обновить его с помощью name desc. Он будет повторяться таким же образом, когда пользователь нажимает . Я новичок, не могли бы вы мне помочь?

John 21.03.2019 14:23

Не держите на меня зла, @fahad tufail, но, пожалуйста, не используйте setTimeout() вот так: это может сработать, но на самом деле это не очень хороший способ сделать это, совсем нет. По второму вопросу, который вы задали, посмотрите мой ответ ниже, я добавляю туда код (было бы «плохо видеть» здесь, в комментарии)

Jolly 21.03.2019 14:34

@Jolly, я полностью согласен с тем, что использование setTimeOut вообще не является хорошей практикой. но для него это решает его проблему.

fahad tufail 21.03.2019 14:58

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