Коли використовувати React setState зворотного дзвінка


191

Коли стан компонента реагування змінюється, викликається метод візуалізації. Отже, для будь-яких змін стану може бути виконана дія в тілі методів візуалізації. Чи існує конкретний випадок використання для зворотного виклику setState?


4
Наразі незрозуміло, про що ви питаєте. Чи можете ви включити якийсь код?
Давін Тріон

2
Зворотний виклик setState - це все, що ви хочете зробити після того, як стан DEFINITELY було змінено. Оскільки setState є асинхронним, якщо ви хочете зателефонувати в fx і бути впевненим, що новий стан завантажений, то для цього і є зворотний виклик
Jayce444,

3
Випадок використання для зворотного виклику setState досить зрозумілий. Ви використовуєте його, коли потрібно запустити функцію після оновлення стану SPECIFIC. Якщо render()замість цього ввести цю функцію , вона запускатиметься кожного разу, коли будь-який стан оновлюється, що, мабуть, не те, що потрібно. Це також зробить ваш код менш читабельним та логічним.
M3RS

Відповіді:


224

Так, є, оскільки setStateпрацює певним asynchronousчином. Це означає , що після виклику setStateв this.stateзмінної не відразу змінилося. тому, якщо ви хочете виконати дію відразу після встановлення стану змінної стану, а потім повернути результат, зворотний виклик буде корисним

Розглянемо приклад нижче

....
changeTitle: function changeTitle (event) {
  this.setState({ title: event.target.value });
  this.validateTitle();
},
validateTitle: function validateTitle () {
  if (this.state.title.length === 0) {
    this.setState({ titleError: "Title can't be blank" });
  }
},
....

Вищевказаний код може не працювати, як очікувалося, оскільки titleзмінна може не мутуватись до того, як на ній буде проведена перевірка. Тепер вам може бути цікаво, що ми можемо виконати валідацію в самій render()функції, але було б кращим і більш чистим способом, якщо ми можемо впоратися з цим у самій функції changeTitle, оскільки це зробить ваш код більш організованим і зрозумілішим

У цьому випадку корисний зворотний дзвінок

....
changeTitle: function changeTitle (event) {
  this.setState({ title: event.target.value }, function() {
    this.validateTitle();
  });

},
validateTitle: function validateTitle () {
  if (this.state.title.length === 0) {
    this.setState({ titleError: "Title can't be blank" });
  }
},
....

Іншим прикладом буде те, коли ви хочете, dispatchі діяти, коли стан змінився. ви хочете робити це у зворотному render()дзвінку, а не тому, як воно буде викликатись кожного разу, коли відбудеться рендерінг, і, отже, можливе багато таких сценаріїв, коли вам знадобиться зворотний виклик.

Інший випадок - це API Call

Може виникнути випадок, коли вам потрібно здійснити виклик API на основі певної зміни стану, якщо ви це зробите в методі візуалізації, він буде викликаний при кожній onStateзміні візуалізації або через те, що деякий Prop перейшов до Child Componentзміненого.

У цьому випадку ви хочете використовувати a, setState callbackщоб передати оновлене значення стану виклику API

....
changeTitle: function (event) {
  this.setState({ title: event.target.value }, () => this.APICallFunction());
},
APICallFunction: function () {
  // Call API with the updated value
}
....

3
Я розумію, що це асинхронний характер. Моє запитання: чи є щось конкретне, що для цього може використовуватися лише функція зворотного виклику setState, можливо, тіло методів візуалізації може не підтримувати (Щось крім, скажімо, кращої читабельності коду.)
Sahil Jain

@SahilJain Валідація - правильний приклад, ви не хочете обробляти його у функції render (), оскільки тоді вона буде викликатися кожен раз, коли ви внесете будь-які зміни у візуалізації (), ви б хотіли викликати її лише тоді, коли змінюється лише вхід, а отже у самій функції
Shubham Khatri

React забороняє змінювати стан під час візуалізації. Отже, його право вводити перевірку у зворотний виклик.
webdeb

if (this.title.length === 0) {має бути this.state.title.length, правда?
Дмитро Міньковський

4
Випадок першого використання, мабуть, не є хорошою ідеєю. setState викликає зворотні виклики після повторного відтворення, тому ви викликаєте подвійне візуалізація без поважних причин. Це саме мета аргументу функції (оновлення). Можна просто запустити, setState(state => state.title.length ? { titleError: "Title can't be blank" } : null)і зміна складеться. Подвійних рендерів не потрібно.
R Есмонд

47
this.setState({
    name:'value' 
},() => {
    console.log(this.state.name);
});

14
Дякуємо за цей фрагмент коду, який може надати деяку обмежену та негайну допомогу. Належне пояснення було б значно поліпшити свою довгострокову цінність , показуючи , чому це хороше рішення проблеми, і зробить його більш корисним для читачів майбутніх з іншими подібними питаннями. Будь ласка, відредагуйте свою відповідь, щоб додати пояснення, включаючи зроблені вами припущення.
Machavity

1
Коли ви хочете викликати функцію після зміни стану, ви можете використовувати метод.
Араз Бабаєв

що робити, якщо ви хочете встановити декілька державних прав, таких як ім'я, ім'я тощо?
Sumanth Varada

44

1. Випадок використання, який мені приходить в голову, - це apiдзвінок, який не повинен переходити в візуалізацію, оскільки він буде працювати на eachзміну стану. І виклик API повинен виконуватись лише у спеціальних змінах стану, а не на кожному рендерінгу.

changeSearchParams = (params) => {
  this.setState({ params }, this.performSearch)
} 

performSearch = () => {
  API.search(this.state.params, (result) => {
    this.setState({ result })
  });
}

Отже, для будь-яких змін стану може бути виконана дія в тілі методів візуалізації.

Дуже погана практика , оскільки render-метод повинен бути чистим, це означає, що жодних дій, змін стану, викликів api, не слід виконувати, просто складіть свій погляд і поверніть його. Дії слід виконувати лише на деяких подіях. Візуалізація - це не подія, а componentDidMountнаприклад.


25

Розгляньте setState call

this.setState({ counter: this.state.counter + 1 })

ІДЕЯ

setState може викликатися функцією асинхронізації

Тому ви не можете розраховувати this. Якщо вищевказаний виклик здійснювався всередині функції асинхронізації, thisбуде позначатися стан компонента на той момент часу, але ми очікували, що це стосується властивості всередині стану в момент setState виклику або початку завдання асинхронізації. Оскільки завданням було виклик асинхронізації, таким чином, властивість, можливо, змінилася з часом. Таким чином, недостовірне використання thisключового слова для посилання на якусь властивість стану, тому ми використовуємо функцію зворотного виклику, аргументи якої попередніState і реквізити, що означає, коли завдання асинхронізації було виконано, і настав час оновити стан за допомогою виклику setState prevState, буде посилатися на стан тепер, коли setState ще не почався. Забезпечення надійності того, що nextState не буде пошкоджено.

Неправильний кодекс: призведе до корупції даних

this.setState(
   {counter:this.state.counter+1}
 );

Правильний код з setState, що має функцію зворотного дзвінка:

 this.setState(
       (prevState,props)=>{
           return {counter:prevState.counter+1};
        }
    );

Таким чином, коли нам потрібно оновити наш поточний стан до наступного стану, виходячи з значення, яке має властивість саме зараз, і все це відбувається асинхронним способом, добре використовувати setState як функцію зворотного виклику.

Я спробував пояснити це в codepen тут CODE PEN

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.