Перейдите к списку «Родная квартира», чтобы перейти к новому экрану при нажатии на элемент - PullRequest
1 голос
/ 15 марта 2019

Я новичок в React Native и сталкиваюсь с проблемой, когда пытаюсь создать плоский список, переходящий на другой экран с деталями элемента при нажатии на элемент списка. Я использую Redux и React-native-router-flux для навигации между экранами. плоский список отображается, но я не могу перейти к другому экрану при нажатии на элемент.

вот мой код:

class MyListItem extends React.PureComponent {

  _onPress = () => {

    this.props.onPressItem(this.props.item);

  };

  render() {

    return (
      <TouchableOpacity

        {...this.props}
        onPress={this._onPress}>
        <View style={styles.GridViewContainer} >
          <Text style={styles.GridViewTextLayout} >{this.props.item.name}</Text>
        </View>
      </TouchableOpacity>
    );
  }
}
class CustomersList extends Component {
  componentWillMount() {
    this.props.getCustomers();

  }

  componentDidUpdate(prevProps) {
    if (prevProps.customers !== this.props.customers) {
      this.props.getCustomers();
    }
  }

  _keyExtractor = (item, index) => item._id;

  _onPressItem = (item) => {
    Actions.customerShow({ customer: item });

  };

  _renderItem = ({ item }) => (
    <MyListItem
      id={item._id}
      item={item}
      onPressItem={() => this._onPressItem(item)}
      title={item.name}
    />
  );

  render = () => {
    return (
      <View style={styles.container}>
        <FlatList
          data={this.props.customers}
          keyExtractor={this._keyExtractor}
          renderItem={this._renderItem}
          extraData={this.state}
          numColumns={3}
        />
      </View>
    );
  }
}

const mapStateToProps = (state) => {
  const customers = state.customers;
  console.log(customers);
  debugger
  return { customers };

};


export default connect(mapStateToProps, {
  getCustomers
})(CustomersList);

А вот и Axi API:

export const getCustomers = () => {
    debugger;
    return (dispatch) => {
        dispatch(setCustomerLoading)
        axios
            .get('https://calm-sands-26165.herokuapp.com/api/customers')
            .then(res =>
                dispatch({
                    type: GET_CUSTOMERS,
                    payload: res.data,
                })
            )
            .catch(err =>
                dispatch({
                    type: GET_ERRORS,
                    payload: null
                })
            );
    };
}

стеки маршрутизации:

const RouterComponent = () => {
  return (
    <Router >
      <Scene key="root" hideNavBar>
        <Scene key="auth">
          <Scene key="login" component={LoginForm} title="Please Login" initial />
        </Scene>
        <Scene key="main">
          <Scene
            onRight={() => Actions.customerCreate()}
            rightTitle="Add"
            key="customersList"
            component={CustomersList}
            title="Customers"
            initial
          />
          <Scene key="customerCreate" component={CustomerCreate} title="Create Customer" />
          <Scene key="customerShow" component={CustomerShow} title="Show Customer" />
        </Scene>
      </Scene>



    </Router>
  );
};

Спасибо заранее,

1 Ответ

1 голос
/ 19 марта 2019

Ошибка, которую вы получаете, возникает, когда источник данных, переданный на FlatList, не является массивом. В вашем случае this.props.customers не определено, пока не будет возвращена функция this.props.getCustomers().

Я бы предложил использовать состояние для отображения плоского списка в вашем CustomersList компоненте. И обновите состояние, когда результаты будут возвращены из асинхронного вызова axios this.setState({customers : nextProps.customers}), который переопределяет FlatList с массивом клиентов.

class CustomersList extends Component {

  constructor(props){
    super(props);
      this.state = {
      customers : []
    };
  }
  ...

  render = () => {
    return (
      <View style={{flex:1}}>
        {this.state.customers.length > 0 ?
        <FlatList
          data={this.state.customers}
          keyExtractor={this._keyExtractor}
          renderItem={this._renderItem}
          extraData={this.state}
          numColumns={1}
      /> :
        <View style={styles.container}>
          <ActivityIndicator size={'large'}/>
        </View>
        }
      </View>
    );
  }
}

Что касается вашей навигации, я сам проверил ваш код, и он работал :) (Как вы можете видеть, я использовал <ActivityIndicator /> для рендеринга, когда список все еще выбирается.

Navigation Example Demo

...