Рассмотрим следующий код React Native:
import React from 'react';
import {Text, View, StyleSheet, Button} from 'react-native';
export default class Target extends React.Component {
constructor(props){
super(props);
this.state = { isLoading: true};
this.hitData = this.props.hitData;
}
componentDidMount(){
for(let i of Object.keys(this.hitData)){
if (this.hitData[i] === 0){
this.hitData[i] = '---'
}
}
this.setState({
prop1: this.hitData['prop1'],
prop2: this.hitData['prop2'],
prop3: this.hitData['prop3'],
prop4: this.hitData['prop4'],
prop5: this.hitData['prop5'],
isLoading: false
});
this.onPress = this.onPress.bind(this);
}
componentDidUpdate(prevProps) {
// console.info(prevProps)
if (this.props.hitData !== prevProps.hitData){
console.info("Component "+ this.state.mac + " got new props!");
this.hitData = this.props.hitData;
this.setState((state, props) =>{
let newState = {};
for(let i of Object.keys(props.hitData))
{
if (state[i] !== props.hitData[i])
{
console.info(i + " is different!");
newState[i] = props.hitData[i]
}
}
return newState
});
}
}
onPress(txt) {
console.info(txt);
}
render(){
return(
<View style = {styles.container}>
<View style = {{flex: 1, flexDirection: 'row'}}>
<View style = {{borderWidth: 2.5, borderColor: '#00FF00',width: '50%'}}>
<Text style = {{fontSize: 19, fontWeight: 'bold'}}>{this.state.prop1}</Text>
<Text style = {{fontSize: 16}} numberOfLines = {1}>{this.state.prop2}</Text>
</View>
<View>
<Text>{"Prop3: " + this.state.prop3}</Text>
<Text>{"Prop4: " + this.state.prop4}</Text>
<Text>{"Prop5: " + this.state.prop4}</Text>
</View>
</View>
<Button key = {this.hitData[0]} title = {"BUTTON"} onPress = {() => this.onPress(this.hitData[0])}/>
</View>
);
}
}
const styles = StyleSheet.create({
container: {
borderRadius: 4,
borderWidth: 2.5,
height: 100,
marginBottom: 5,
overflow: 'hidden'
}
});
Это код компонента React Native. Компонент принимает информацию, полученную от EventSource в родительском элементе. Цель состоит в том, чтобы обновить поля, содержащие Prop[3-5], на основе данных о будущих событиях.
В родительском компоненте у меня есть свойство для каждого элемента в state, и я определяю каждый элемент, например:
const targetList = this.state.filterKeys.map((item) =>
<Target key = {item} hitData = {this.state[item]['lastHit']}/>
В моем обработчике событий я могу сделать:
this.setState({
[id]: hitIntermediate
})
для отправки новых реквизитов каждому дочернему компоненту.
В моем дочернем компоненте я вижу поступление новых реквизитов, но после первого обновления дочерний компонент перестает обновляться. Неважно, сколько событий я отправляю, после получения первого обновления дальнейшие обновления не отображаются.
Странная часть заключается в том, что если я запрашиваю this.state в дочернем компоненте, я вижу, что состояние отражает данные из нового события, но отображение не меняется.
Я что-то здесь совсем не понимаю. По сути, я хочу сделать эквивалент установки .innerHTML для тегов <Text>, содержащих различные фрагменты данных, но все мои обновления, похоже, игнорируются после первого.



![Безумие обратных вызовов в javascript [JS]](https://i.imgur.com/WsjO6zJb.png)


Я смог решить это самостоятельно.
Как оказалось, способ, которым я добавлял события в свой компонент, был глупым. Я изменил его, поэтому вместо того, чтобы поддерживать чрезвычайно сложное состояние в основном компоненте, я просто передаю EventSource и определяю обработчик событий внутри каждого дочернего компонента.
Теперь я вижу обновления почти в режиме реального времени. Я все еще хотел бы немного улучшить производительность повторного рендеринга, но в целом проблема, с которой я столкнулся, решена.
Теперь небольшой дополнительный вопрос: почему я вижу (немного) более высокую производительность, если у меня запущены реактивные инструменты разработки?
Я не знаю, какой браузер вы используете и как он справляется с этим, но если вкладка, которую вы используете для отладки, не сфокусирована (это фоновая вкладка) из-за того, как, например. Chrome обрабатывает фоновые вкладки, обновление займет немного больше времени