Почему действие заменителя filterPlayers () не вызывает повторную визуализацию? Я думал, что в случае с приставкой каждый раз, когда я пропускаю действие, он будет перерисовывать связанный компонент. Разве это не так, как это работает?
Чтобы попытаться обойти визуальные элементы без обновления, я попытался использовать componentDidUpdate и протестировать playerListFilterType
prop на предмет изменений. Сама функция фильтра работает, я также заметил, что если я выберу следующий фильтр, мой визуальный список обновится, чтобы показать предыдущий отфильтрованный список.
Быстрая разбивка:
Я добавляю свойство класса visiblePlayers
, которое содержит список игроков для отображения на экране.
Я заполняю свойство следующей функцией:
getVisiblePlayers = () => {
this.visiblePlayers = this.props.playerList.filter(player => player.visible === true)
}
При нажатии кнопки я запускаю действие переупорядочения, которое настраивает свойство видимости для каждого игрока, однако это не вызывает повторного рендеринга (почему?) Экрана, поэтому для облегчения захвата обновления я использую метод componentDidUpdate () :
componentDidUpdate(prevProps) {
if (prevProps.playerListFilterType !== this.props.playerListFilterType) {
this.getVisiblePlayers()
}
}
Затем я просто передаю visiblePlayers в PlayerList, который обеспечивает вывод данных на экран
<PlayerList
playerList={this.visiblePlayers}
fetchingData={this.props.fetchingData}
handleDataRequest={this.fetchPlayersAsync} />
Когда я выполняю код в отладчике, я нажимаю точку останова в getVisiblePlayers()
при нажатии кнопки фильтра. Я также вижу правильный список в this.visiblePlayers
, когда getVisiblePlayers
заканчивается, однако он не входит в метод render () после этого, и я предполагаю, почему в моем списке показаны результаты предыдущего фильтра.
Вот как выглядит полный код:
class PlayerListScreen extends React.Component {
static navigationOptions = ({ navigation }) => {
return {
headerTitle: navigation.getParam('headerButton'),
headerRight: <Ionicons name='md-more' size={25} style={{ marginRight: 20 }} />
}
}
async componentDidMount() {
await this.fetchPlayersAsync();
}
componentDidUpdate(prevProps) {
if (prevProps.playerListFilterType !== this.props.playerListFilterType) {
this.getVisiblePlayers()
}
}
setNavigationParams = () => {
this.props.navigation.setParams({
headerButton: this.headerButton
})
}
// navigation header element
headerButton = () => (
<NavigationHeaderTitle
handleDataRequest={this.fetchPlayersAsync}
titleMessage={
(this.props.fetchingData)
? 'fetching list of players'
: `${this.props.playerList.length} online`
} />
)
fetchPlayersAsync = async () => {
await this.props.fetchPlayerListAsync();
this.getVisiblePlayers()
this.setNavigationParams()
}
visiblePlayers = []
getVisiblePlayers = () => {
this.visiblePlayers = this.props.playerList.filter(player => player.visible === true)
}
render() {
return (
<View>
<PlayerListOptionsBar
handleFiltering={this.props.filterPlayers}
playerList={this.props.playerList} />
<PlayerList
playerList={this.visiblePlayers}
fetchingData={this.props.fetchingData}
handleDataRequest={this.fetchPlayersAsync} />
</View>
)
}
}
const mapStateToProps = state => {
return {
fetchingData: state.player.fetchingData,
playerList: state.player.playerList,
playerListFilterType: state.player.playerListFilterType
}
};
export default connect(mapStateToProps, { fetchPlayerListAsync, filterPlayers })(PlayerListScreen)