react-native redux道具更改回未定义

时间:2018-09-07 03:51:19

标签: react-native redux react-redux

我正在尝试向我的应用添加过滤器,但是由于某些原因,<Picker>组件中的selectedValue不坚持我选择的选项。我可以在左上方看到过滤器文本从“ all”更改为“ lobby”,但是,一旦播放器列表完全呈现,它就会变回“ all”。并且playerListFilterType属性设置为undefined。我在调试器中逐步执行了代码,直到列表重新呈现为止,它一直处于“大厅”状态。该操作本身有效,因此列表显示了准确的结果。

这是我的代码:

import React from 'react'
import { View, Picker } from 'react-native'
import PlayerList from '../components/PlayerList'
import { fetchPlayerListAsync, filterPlayers } from '../redux/actions/player_actions';

import NavigationHeaderTitle from '../components/NavigationHeaderTitle'
import PlayerStatusFilterPicker from '../components/pickers/PlayerStatusFilterPicker'

import { connect } from 'react-redux'

class PlayerListScreen extends React.Component {

  static navigationOptions = ({ navigation }) => {
    const playerStatusFilterPicker = (
      <PlayerStatusFilterPicker
        playerListFilterType={navigation.getParam('playerListFilterType')}
        filterPlayers={navigation.getParam('filterPlayers')}
        playerList={navigation.getParam('playerList')}
      />
    )

    return {
      headerTitle: navigation.getParam('headerButton'),
      headerRight: playerStatusFilterPicker
    }
  }

  async componentDidMount() {
    await this.fetchPlayersAsync();
  }

  setNavigationParams = () => {
    this.props.navigation.setParams({
      headerButton: this.headerButton,
      playerList: this.props.playerList,
      playerListFilterType: this.props.playerListFilterType,
      filterPlayers: this.props.filterPlayers
    })
  }

  // 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.setNavigationParams()
  }

  render() {
    return (
      <View>
        <PlayerList
          playerList={this.props.playerList}
          fetchingData={this.props.fetchingData}
          handleDataRequest={this.fetchPlayersAsync}
        />
      </View>
    )
  }
}

const mapStateToProps = state => {
  return {
    fetchingData: state.player.fetchingData,
    playerList: state.player.playerList,
    unfilteredPlayerList: state.player.unfilteredPlayerList,
    playerListFilterType: state.player.playerListFilterType
  }
};

export default connect(mapStateToProps, { fetchPlayerListAsync, filterPlayers })(PlayerListScreen)

这是过滤器组件的外观,但我不认为问题出在这里:

import React, { Component } from "react";
import { 
  View,
  Picker
} from "react-native";
import * as constants from '../../constants'

class PlayerStatusFilterPicker extends Component {
  render() {
    return (
      <View>
        <Picker 
          selectedValue={this.props.playerListFilterType}
          onValueChange={(itemValue) => this.props.filterPlayers(itemValue, this.props.playerList)}
          style={{ height: 40, width: 100 }}
        >
          <Picker.Item label='all' value='all' />
          <Picker.Item label="lobby" value={constants.IN_LOBBY} />
          <Picker.Item label="in game" value={constants.IN_GAME} />
        </Picker>
      </View>
    );
  }
}
export default PlayerStatusFilterPicker;

这是减速器的样子:

    // show only the players that are waiting in the main lobby
case actionTypes.SHOW_PLAYERS_IN_LOBBY: {
  const filteredList = action.payload.filter(player => player.status === constants.IN_LOBBY)
  return { playerList: filteredList, playerListFilterType: constants.IN_LOBBY, fetchingData: false }
}

// show only the players that are currently playing
case actionTypes.SHOW_PLAYERS_IN_GAME: {
  const filteredList = action.payload.filter(player => player.status === constants.IN_GAME)
  return { playerList: filteredList, playerListFilterType: constants.IN_LOBBY, fetchingData: false }
}

enter image description here

1 个答案:

答案 0 :(得分:0)

使用componentDidUpdate生命周期方法修复了该问题。像这样:

componentDidUpdate(prevProps) {
if (this.props.playerListFilterType != prevProps.playerListFilterType) {
  this.props.navigation.setParams({
    playerListFilterType: this.props.playerListFilterType
  })
}

}