Реакция: ненужное обновление компонента

90
8

Есть 3 реагирующих компонента, два из них внутри первого. Первый компонент содержит некоторое состояние, которое используется только в третьем компоненте. Когда я обновляю состояние от третьего компонента с помощью обратного вызова, дополнительно обновляю второй компонент. Но второй компонент не имеет никаких изменений.

Почему это происходит и как его избежать?

вот мой код:

var app = React.createClass({
displayName: 'app',

settingsChanged: function (value) {
console.log('app.settingsChanged');
this.setState({ settings: { value: value } });
},

getInitialState: function() {
return { settings: { value: 1 } }
},

render: function() {
return (
React.createElement('div', null,
React.createElement(component1),
React.createElement(component2, { settings: this.state.settings, settingsChanged: this.settingsChanged })
)
);
}
})

var component1 = React.createClass({
displayName: 'component1',

render: function () {
console.log('component1.render');
return (
React.createElement('div', null, 'component1')
);
}
})

var component2 = React.createClass({
displayName: 'component2',

tbValueChanged: function(e) {
this.props.settingsChanged(e.target.value);
},

render: function () {
console.log('component2.render');
return (
React.createElement('div', null,
React.createElement('div', null, 'component2'),
React.createElement('input', { value: this.props.settings.value, onChange: this.tbValueChanged })
)
);
}
})

В консоли я вижу следующее:

component1.render app.js:27
component2.render app.js:42
app.settingsChanged app.js:5
component1.render app.js:27
component2.render app.js:42

http://jsfiddle.net/67m0z3ts/1/

спросил(а) 2015-11-26T15:04:00+03:00 4 года, 10 месяцев назад
1
Решение
58

На самом деле, что происходит, это нормальное поведение, когда в главном компоненте что-то изменилось, все компоненты в этом основном будут снова отображены.

НО хорошие новости о том, что вы можете изменить это поведение по умолчанию, используя shouldComponentUpdate(), который по умолчанию является истинным. Взгляните на документацию react.js в расширенной производительности.

Надеюсь, это поможет.

Удачи

ответил(а) 2015-11-26T16:14:00+03:00 4 года, 10 месяцев назад
57

Я не хочу вдаваться в подробности здесь, но в дополнение к другим ответам вы можете попытаться включить PureRenderMixin из React. Из документов:

Под капотом mixin реализует shouldComponentUpdate, в котором он сравнивает текущие реквизиты и состояние со следующими и возвращает false если проходят равенства.

ответил(а) 2015-11-26T16:36:00+03:00 4 года, 10 месяцев назад
57

Вы можете предотвратить рендеринг с помощью метода shouldComponentUpdate. Поэтому вы должны добавить эти строки кода в свой компонент1:

    getInitialState : function(){
return {
shouldUpdate: true
}
},
shouldComponentUpdate: function(nextProps, nextState){
return nextState === this.state.shouldUpdate
},

А также Fiddle Link


Надеюсь, это поможет вам!

благодаря

ответил(а) 2015-11-26T16:10:00+03:00 4 года, 10 месяцев назад
Ваш ответ
Введите минимум 50 символов
Чтобы , пожалуйста,
Выберите тему жалобы:

Другая проблема