setState проти replaceState у React.js


96

Я новачок у бібліотеці React.js, я переглядав деякі підручники і натрапив:

  • this.setState
  • this.replaceState

Наведений Опис не дуже чіткий (ІМО).

setState is done to 'set' the state of a value, even if its already set 
in the 'getInitialState' function.

Аналогічно

The replaceState() method is for when you want to clear out the values 
already in state, and add new ones.

Я спробував this.setState({data: someArray});слідувати, this.replaceState({test: someArray});а потім console.logged їх, і я виявив, що stateзараз є dataі test.

Потім я спробував this.setState({data: someArray});, this.setState({test: someArray});а потім і console.logged їх, і я виявив, що stateзнову були dataі test.

Отже, яка саме різниця між ними?


1
Ваш перший приклад неточний. replaceState видалить попередній стан. Ймовірно, ви тестуєте його неправильно.
Brigand

1
Я не шукав змін у зворотному дзвінку. Можливо, тому ..
myusuf

Відповіді:


138

З setStateпоточним і попереднім станами відбувається злиття. З replaceState, він викидає поточний стан, і замінює його тільки те , що ви надаєте. Зазвичай setStateвикористовується, якщо вам дійсно не потрібно видалити ключі з якихось причин; але встановлення для них значення false / null зазвичай є більш чіткою тактикою.

Хоча це можливо, це може змінитися; В даний час replaceState використовує об’єкт, переданий як стан, тобто replaceState(x)після встановлення this.state === x. Це трохи легше setState, тому його можна використовувати як оптимізацію, якщо тисячі компонентів часто встановлюють свої стани.
Я стверджував це за допомогою цього тесту .


Якщо ваш поточний стан {a: 1}і ви телефонуєте this.setState({b: 2}); коли буде застосовано державу, воно буде {a: 1, b: 2}. Якби ви телефонували, this.replaceState({b: 2})ваша держава була б такою {b: 2}.

Примітка: Держава встановлюється не відразу, тому не слід робити це this.setState({b: 1}); console.log(this.state)під час тестування.


1
Мені досі незрозуміло. Чи можете ви навести приклад, коли використання одного над іншим змінює результат, тобто це злиття, про яке ви маєте на увазі ...
Серж Саган

1
Як існує попередній стан і поточний стан, як у, як ми можемо отримати до них доступ? Крім того, я передав об’єкт для заміни стану, але все ж дані попереднього стану все ще були наявні.
myusuf

1
То коли встановлюється держава? Як коли я можу console.log це і перевірити?
myusuf

21
@myusuf.setState({...}, callback)
Brigand

46

Визначення на прикладі:

// let's say that this.state is {foo: 42}

this.setState({bar: 117})

// this.state is now {foo: 42, bar: 117}

this.setState({foo: 43})

// this.state is now {foo: 43, bar: 117}

this.replaceState({baz: "hello"})

// this.state. is now {baz: "hello"}

Зверніть увагу на це з документів , хоча:

setState () не одразу мутує цей.state, але створює перехід у стані очікування. Доступ до цього.state після виклику цього методу може потенційно повернути існуюче значення.

Те саме стосується replaceState()


14

Згідно з документами , replaceStateможе припинитися:

Цей метод недоступний для компонентів класу ES6, які розширюють React.Component. Його можна повністю видалити в майбутній версії React.


Чи існує подібний метод заміни?
zero_cool

1
Для "подібного" методу ви можете використовувати this.setState ({all: undefined, old: undefined, keys: undefined, new: value})
Wren

@ Wren, що це? Це офіційний підпис для скидання стану?
Зелений

Ні, це просто явне встановлення попередньо існуючого стану на невизначений, що є результатом "replaceState" без усіх існуючих ключів.
Рен

2

Оскільки replaceStateзараз застарілий, ось дуже простий спосіб вирішення. Хоча, мабуть, досить рідко ви б / повинні вдаватися до цього.

Щоб видалити стан:

for (const old_key of Object.keys(this.state))
    this.setState({ [old_key]: undefined });

Або, якщо ви не хочете мати кілька дзвінків на setState

const new_state = {};
for (const old_key of Object.keys(this.state))
    new_state[old_key] = undefined;
this.setState(new_state);

По суті, усі попередні ключі у стані тепер повертаються undefined, що дуже легко можна відфільтрувати за допомогою ifоператора:

if (this.state.some_old_key) {
    // work with key
} else {
    // key is undefined (has been removed)
}

if ( ! this.state.some_old_key) {
    // key is undefined (has been removed)
} else {
    // work with key
}

У JSX:

render() {
    return <div>
        { this.state.some_old_key ? "The state remains" : "The state is gone" }
    </div>
}

Нарешті, щоб "замінити" стан, просто об'єднайте новий об'єкт стану з копією старого стану, який вже був undefined, і встановіть його як стан:

const new_state = {new_key1: "value1", new_key2: "value2"};
const state = this.state;

for (const old_key of Object.keys(state))
    state[old_key] = undefined;

for (const new_key of Object.keys(new_state))
    state[new_key] = new_state[new_key];

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