#reactjs #react-redux
#reactjs #реагирует-redux
Вопрос:
Работаю над проектом ReactJS, и я знаю, что мы не изменяем состояние (обычно я этого не делаю, но не знаю точной причины), поэтому я просто попробовал какой-то неправильный подход, даже если он работает правильно.
import logo from './logo.svg';
import './App.css';
import Test from './test';
import {Home, NotFoundComponent,Contact, Profile} from './test/home'
import {
BrowserRouter as Router,
Route,
Link
} from 'react-router-dom'
import React, {Component} from 'react';
class App extends Component {
constructor(props) {
super(props);
this.state = {
list: [42, 33, 68],
};
}
onUpdateItem = i => {
this.state.list[i] ;
this.setState({
list: this.state.list,
})
// this.setState(state => {
// const list = state.list.map((item, j) => {
// if (j === i) {
// return item 1;
// } else {
// return item;
// }
// });
// return {
// list,
// };
// });
};
render() {
return (
<div>
<ul>
{this.state.list.map((item, index) => (
<li key={item}>
The person is {item} years old.
<button
type="button"
onClick={() => this.onUpdateItem(index)}
>
Make me one year older
</button>
</li>
))}
</ul>
</div>
);
}
}
export default App;
this.state.list[i] ;
this.setState({
list: this.state.list,
})
в чем проблема, когда я обновляю приведенный выше код вместо метода map, оба дают правильный вывод?
объясните мне это за ссылкой на изолированную среду кода сцены
Комментарии:
1. В вашем подходе нет ничего плохого, если только ваше состояние не является
immutable
. Но будьте осторожны, когда работаете со ссылочными типами. Но если у вас есть дочерние элементы, зависящие от родительскогоlist
элемента, он не обновляет дочерние элементы.2. потому что оба типа ссылок равны, а содержимое отличается только тем, что дочерний элемент не может распознать его правильно?
3. Правильно!!!
4. Я создал здесь пример. Проверьте это stackblitz.com/edit/react-wt5tf4?file=src/Child.js
5. братан, какая часть react знает, что оба ссылки одинаковы, поэтому нам не нужно обновлять пользовательский интерфейс, это жизненный цикл render() или shoulcomponemtUpdate()
Ответ №1:
Вот причина:
Когда вы изменяете массив, скажем list[i]
, идентификатор массива не изменяется, поэтому listBefore ==== listAfter
, пока вы сопоставляете массив listBefore !== listAfter
, при вызове setState
ВСЕ дочерние компоненты будут вызываться снова по умолчанию, даже если вы ничего не помещаете внутрь setState
. Потому что react не может определить, требуется ли обновление дочерних элементов по умолчанию, и на самом деле это пустая трата ресурсов.
Вы можете предотвратить это, сообщив дочерним элементам «НЕ обновлять», вызвав shouldComponentUpdate
или просто используя PureComponent
.
И способ определить, необходимы ли обновления, — сравнить, используя ===
Кроме того, даже если вы не заботитесь о производительности. вы никогда не должны этого делать. В некоторых случаях это приведет к некоторым отладочным ошибкам, главным образом потому, что обновления в react НЕ синхронизированы. Я никогда не сталкиваюсь с этим, потому что я даже не осмеливаюсь попробовать
Комментарии:
1. если я обновлю throgh this.state.list.map((значение, индекс)=>{ означает, что дочерний элемент не будет обновляться?
2. @SelvaGanapathi дочерние элементы ВСЕГДА будут обновляться по умолчанию, даже если вы вызываете
setState({})
(пустой объект), вы можете подтвердить то, что я говорю, введяconsole.log
дочерние элементы
Ответ №2:
При обновлении state
вы должны позаботиться о immutable
.
onUpdateItem = i => {
//this.state.list[i] ;
//this.setState({
// list: this.state.list,
//})
this.setState({
list: this.state.list.map((value,index)=>{
if(i === index) return value 1;
return value;
})
});
}
Если вы не поддерживаете неизменяемость, ваше приложение не будет работать так, как вы ожидали.
Состояния React обновляются в соответствии с жизненным циклом. если без неизменности, это означает, что вы нарушаете жизненный цикл.
Комментарии:
1. Я знаю, что, если я не поддерживаю неизменяемый?
2. Он спросил, почему, и вы рассказали ему, как