Моя проблема
https://imgur.com/fHHqSqF
Обратите внимание, что когда появляется список, я сразу нажимаю на первый элемент, но рендеринг занимает 5 секунд ... У меня та же проблемакогда я удаляю элемент из списка: https://imgur.com/1ChZYBy.
Когда я выхожу из режима отладки, он намного более отзывчив, когда список появляется, но все еще медленный, когда я удаляю элемент.
Что яуже попробовал:
- Устанавливая реагирующий нативный отладчик, я не смог найти ничего плохого в своем редуксе, но я подозреваю тот факт, что когда я удаляю элемент из моего списка, я делаю array.filter вдля того, чтобы мой новый магазин был представлен в redux, который, кажется, не самый лучший для производительности
- console.log, чтобы видеть каждый раз, когда компонент рендерит
- Transformmed
TripCell
и typedTripList
из классов вфункциональные компоненты - Пытался поставить
shouldComponentUpdate() { return false }
почти везде, где мог
Что я подозреваю
- Я подозреваю
TripCell
, чтобы сделать рендеринг много раз - Может быть, я должен реализовать Redux Logic, а не into мой HOC, но прямо в моем
TripList
? - Я могу попытаться также преобразовать свой список, чтобы он стал функциональным компонентом
- Может быть, список должен быть разрешен для получения данных из API, яследует ли разрешить эту задачу моему HOC?
Архитектура моего кода
TripListAllScreen
- это экран, который показывает все поездки
TripListDriverScreen
- это экранкоторый показывает все поездки, в которых пользователь является драйвером
Некоторые журналы при записи видео
Должно быть макс. 62 рендера, потому что здесь LIST_ALL
содержит то же самое, что и LIST_DRIVER
, и у меня всего 26 поездок.
Мой код
TripListAllScreen
export default class TripListAllScreen extends Component {
render() {
console.log(`RENDER : ${this.constructor.name}`);
return (
<View style={[{ flex: 1 }]}>
<TripList listType={LISTE_ALL} />
</View>
);
}
}
typedTripList
function typedTripList(WrappedTripList) {
return function TypedTripList(props) {
const {
listType, dataList, setDataList, setSelectedTrip, setSelectedGeneralTrip, token,
} = props;
let route;
switch (listType) {
case LISTE_ALL:
route = '/trip/get';
break;
case LIST_DRIVER:
route = '/trip/getWhereUserIsDriver';
break;
default:
route = '/trip/get';
}
console.log(`typedTripList.${props.listType}`);
return (
<WrappedTripList
route={route}
dataList={dataList}
setDataList={setDataList}
setSelectedTrip={setSelectedTrip}
setSelectedGeneralTrip={setSelectedGeneralTrip}
token={token}
/>
);
};
}
const mapStateToProps = (state, ownProps) => ({
// Determine the redux dataList to use <all trips | where user is driver | where user is passenger>
dataList: state.datalist[ownProps.listType],
token: state.token.token,
});
const mapDispatchToProps = (dispatch, ownProps) => ({
// Determine the redux dataList to use in set data list action
// <all trips | where user is driver | where user is passenger>
setDataList: data => dispatch(setDataListAction(data, ownProps.listType)),
setSelectedTrip: idRecurrence => dispatch(setSelectedTripAction(idRecurrence)),
setSelectedGeneralTrip: idTrajet => dispatch(setSelectedGeneralTripAction(idTrajet)),
});
typedTripList.propTypes = {
listType: PropTypes.string.isRequired,
};
// Fixed the problem ! :)
const composedHoc = compose(
connect(mapStateToProps, mapDispatchToProps),
typedTripList,
);
export default composedHoc;
TripList.js
class TripList extends Component {
state = {
isReady: false,
refreshing: false,
}
constructor(props) {
super(props);
this._getTrips();
}
// Trips should be got in typedTripList (OR MAYBE NOT: THEN DIFFICULT TO MANAGE LOADING)
_getTrips = () => {
const { token, setDataList, route } = this.props;
// console.log('GETTING TRIPS');
// console.log(`TOKEN: ${token}`);
protectedGetRequest(route, token) // '/trip/get'
.then(response => response.json())
.then((json) => {
this.setState({ isReady: true });
setDataList(json.data);
})
.then(() => {
this.setState({ refreshing: false });
})
.catch(e => console.log(e));
}
_renderTripCell = ({ item }) => (
<TouchableOpacity onPress={() => this._navToTripDetails(item.idRecurrence, item.Trajet.idTrajet)}>
<TripCell
start={item.Trajet.EtapeTrajets[0].Etape.Nom}
arrival={item.Trajet.EtapeTrajets[item.Trajet.EtapeTrajets.length - 1].Etape.Nom}
datetime={this._renderDatetime(item)}
seats={item.Trajet.NbPlaces}
passengers={item.NbPassagers}
/>
</TouchableOpacity>
);
_renderDatetime = (item) => {
const date = mysqlToJsDate(item.Date);
const dateTime = mysqlToJsDateTime(item.Trajet.HeureDepart);
return {
...date,
hours: dateTime.hours,
minutes: dateTime.minutes,
};
}
_navToTripDetails = (idRecurrence, idTrajet) => {
const { navigation, setSelectedTrip, setSelectedGeneralTrip } = this.props;
const { navigate } = navigation;
// TODO: merge those functions
setSelectedTrip(idRecurrence);
setSelectedGeneralTrip(idTrajet);
navigate('TripDetails');
}
render() {
console.log(`RENDER : ${this.constructor.name}`);
const { isReady, refreshing } = this.state;
const { dataList } = this.props;
if (!isReady) return (<Loading />);
return (
<View style={[styles.container]}>
<FlatList
data={dataList}
keyExtractor={(item, index) => `${item.idRecurrence}-${index}`}
renderItem={this._renderTripCell}
refreshControl={(
<RefreshControl
refreshing={refreshing}
onRefresh={() => { this._getTrips(); }}
/>
)}
/>
</View>
);
}
}
export default typedTripList(withNavigation(TripList));
РЕДАКТИРОВАТЬ
Моя избыточная логика для удаления элементов из списков
case DELETE_ITEM:
console.log('in delete item');
return {
...state,
[LISTE_ALL]: state[LISTE_ALL].filter(item => item.idRecurrence != action.payload.idRecurrence),
[LIST_DRIVER]: state[LIST_DRIVER].filter(item => item.idRecurrence != action.payload.idRecurrence),
[LIST_PASSENGER]: state[LIST_PASSENGER].filter(item => item.idRecurrence != action.payload.idRecurrence),
};