Флаттер и Редукс - PullRequest
       0

Флаттер и Редукс

0 голосов
/ 29 марта 2020

Я пишу пример использования Redux для управления моим состоянием. Я не знаю почему, но когда я запускаю свое приложение, моя консоль выдает мне сообщение об ошибке такого типа:

The getter 'length' was called on null.
Receiver: null
Tried calling: length

Я только начинающий в использовании избыточности, поэтому, пожалуйста, простите, если это будет просто маленькая забавная ошибка:)

Я вставляю код ниже: order_screen.dart

class OrdersScreen extends StatelessWidget{
  void handleInitialBuild(OrdersScreenProps props){
    props.getOrders();
  }

  @override
  Widget build(BuildContext context){
    return StoreConnector<AppState, OrdersScreenProps>(
      converter: (store) => mapStateToProps(store),
      onInitialBuild: (props) => this.handleInitialBuild(props),
      builder: (context, props){
        List<Order> data = props.listResponse.data;
        bool loading = props.listResponse.loading;

        Widget body;
        if(loading){
          body = Center(
            child: CircularProgressIndicator(),
          );
        }else{
          body = ListView.separated(
            padding: const EdgeInsets.all(16.0),
            itemCount: data.length,
            separatorBuilder: (context, index) => Divider(),
            itemBuilder: (context, i) {
              Order order = data[i];

              return ListTile(
                title: Text(
                  order.title,
                ),
                onTap: () {
                  props.getOrderDetails(order.id);
                  Navigator.pushNamed(context, AppRoutes.orderDetails);
                },
              );
            },
          );
        }
        return Scaffold(
          appBar: AppBar(
            title: Text('Orders list'),
          ),
          body: body,
        );
      },
    );
  }
}

class OrdersScreenProps {
  final Function getOrders;
  final Function getOrderDetails;
  final ListOrdersState listResponse;

  OrdersScreenProps({
    this.getOrders,
    this.listResponse,
    this.getOrderDetails,
  });
}

OrdersScreenProps mapStateToProps(Store<AppState> store) {
  return OrdersScreenProps(
    listResponse: store.state.order.list,
    getOrders: () => store.dispatch(getOrders()),
    getOrderDetails: (int id) => store.dispatch(getOrderDetails(id)),
  );
}

order_actions.dart

const LIST_ORDERS_REQUEST = 'LIST_ORDERS_REQUEST';
const LIST_ORDERS_SUCCESS = 'LIST_ORDERS_SUCCESS';
const LIST_ORDERS_FAILURE = 'LIST_ORDERS_FAILURE';

RSAA getOrdersRequest(){
  return RSAA(
    method: 'GET',
    endpoint: 'http://10.0.2.2:80/order',
    types: [
      LIST_ORDERS_FAILURE,
      LIST_ORDERS_REQUEST,
      LIST_ORDERS_SUCCESS
    ],
    headers: {
      'Content-Type':'application/json',
    },
  );
}

ThunkAction<AppState> getOrders() => (Store<AppState> store) => store.dispatch(getOrdersRequest());

const GET_ORDERS_DETAILS_REQUEST = 'GET_ORDERS_DETAILS_REQUEST';
const GET_ORDERS_DETAILS_SUCCESS = 'GET_ORDERS_DETAILS_SUCCESS';
const GET_ORDERS_DETAILS_FAILURE = 'GET_ORDERS_DETAILS_FAILURE';

RSAA getOrderDetailsRequest(int id){
  return RSAA(
    method: 'GET',
    endpoint: 'http://10.0.2.2:80/order/$id',
    types: [
      GET_ORDERS_DETAILS_REQUEST,
      GET_ORDERS_DETAILS_SUCCESS,
      GET_ORDERS_DETAILS_FAILURE
    ],
    headers: {
      'Content-Type':'application-type',
    },
  );
}

ThunkAction<AppState> getOrderDetails(int id) => (Store<AppState> store) => store.dispatch(getOrderDetailsRequest(id));

order_state.dart

class OrderState{
  ListOrdersState list;
  OrderDetailsState details;

  OrderState({
    this.list,
    this.details,
  });

  factory OrderState.initial() => OrderState(
    list: ListOrdersState.initial(),
    details: OrderDetailsState.initial(),
  );
}

class ListOrdersState {
  dynamic error;
  bool loading;
  List<Order> data;

  ListOrdersState({
    this.error,
    this.loading,
    this.data,
  });

  factory ListOrdersState.initial() => ListOrdersState(
    error: null,
    loading: false,
    data: [],
  );
}

class OrderDetailsState {
  dynamic error;
  bool loading;
  OrderDetails data;

  OrderDetailsState({
    this.error,
    this.loading,
    this.data,
  });

  factory OrderDetailsState.initial() => OrderDetailsState(
    error: null,
    loading: false,
    data: null,
  );
}

app_state.dart

@immutable
class AppState {
  final UserState user;
  final OrderState order;

  AppState({
    this.user,
    this.order
  });

  factory AppState.initial() => AppState(
    user: UserState.initial(),
    order: OrderState.initial()
  );

  AppState copyWith({
    UserState user,
    OrderState order,
  }) {
    return AppState(
      user: user ?? this.user,
      order: order ?? this.order,
    );
  }

order_reducer.dart

OrderState orderResucer(OrderState state, FSA action){
  OrderState newState = state;

  switch (action.type) {
    case LIST_ORDERS_REQUEST:
      newState.list.error = null;
      newState.list.loading = true;
      newState.list.data = null;
      return newState;

    case LIST_ORDERS_SUCCESS:
      newState.list.error = null;
      newState.list.loading = false;
      newState.list.data = ordersFromJSONStr(action.payload);
      return newState;

    case LIST_ORDERS_FAILURE:
      newState.list.error = action.payload;
      newState.list.loading = false;
      newState.list.data = null;
      return newState;


    case GET_ORDERS_DETAILS_REQUEST:
      newState.details.error = null;
      newState.details.loading = true;
      newState.details.data = null;
      return newState;

    case GET_ORDERS_DETAILS_SUCCESS:
      newState.details.error = null;
      newState.details.loading = false;
      newState.details.data = orderFromJSONStr(action.payload);
      return newState;

    case GET_ORDERS_DETAILS_FAILURE:
      newState.details.error = action.payload;
      newState.details.loading = false;
      newState.details.data = null;
      return newState;

    default:
      return newState;
  }
}

List<Order> ordersFromJSONStr(dynamic payload) {
  Iterable jsonArray = json.decode(payload);
  return jsonArray.map((j) => Order.fromJSON(j)).toList();
}

OrderDetails orderFromJSONStr(dynamic payload) {
  return OrderDetails.fromJSON(json.decode(payload));
}

1 Ответ

0 голосов
/ 30 марта 2020

Первое, что вам нужно, это выполнить действие для редуктора и вызвать соответствующее действие для изменения состояния.

TypedReducer<OrderState, FSA>(orderReducer>); //pass it your reducers in store

Запустить соответствующее действие

ThunkAction<AppState> getOrders() => (Store<AppState> store) ={
    store.dispatch(FSA(type: LIST_ORDERS_REQUEST);
    store.dispatch(getOrdersRequest().then((orders){
     store.dispatch(FSA(type: LIST_ORDERS_REQUEST);
}), onError(e){
     store.dispatch(FSA(type: LIST_ORDERS_FAILURE);
  }
};

Ваш getOrders () должен возвращать будущее. Весь смысл создания ThunkAction состоит в том, чтобы возвращать функцию, которая затем отправляет регулярные синхронные действия после завершения асинхронной функции внутри нее.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...