为什么我的filterPlayers()redux动作不会导致重新渲染?我认为使用redux时,只要我通过一个动作,它都会重新渲染连接的组件。这不是它的工作原理吗?
要尝试解决未更新的视觉效果,我尝试使用componentDidUpdate并测试playerListFilterType
道具的更改。过滤器功能本身起作用,我还注意到,如果选择下一个过滤器,我的视觉列表将更新以显示上一个过滤器列表。
快速细分:
我要添加一个类别属性visiblePlayers
,该属性保存播放器列表以显示在屏幕上。
我使用以下函数填充属性:
getVisiblePlayers = () => {
this.visiblePlayers = this.props.playerList.filter(player => player.visible === true)
}
按下按钮时,我会触发一个redux操作,该操作会调整每个播放器的可见性属性,但这不会导致屏幕重新呈现(为什么?),因此为了帮助捕获更新,我使用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)