React / Redux - плохая функция поддержки отложенной загрузки состояния в mapStateToProps? - PullRequest
0 голосов
/ 04 декабря 2018

Это мой компонент:

import React, { Component } from "react";
import PropTypes from "prop-types";
import { connect } from "react-redux";
import { Divider } from "antd";
import MovieList from "../components/MovieList";
import IncreaseCountButton from "../components/IncreaseCountButton";
import DeleteButton from "../components/DeleteButton";
import { deleteMovie, increaseCount } from "../actions/movies";
import { getIsDeleting, getIsIncreasing } from "../reducers/actions";

export class MovieListContainer extends Component {
  constructor(props) {
    super(props);
    this.handleIncrease = this.handleIncrease.bind(this);
    this.handleDelete = this.handleDelete.bind(this);
  }

  static propTypes = {
    isIncreasing: PropTypes.func.isRequired,
    isDeleting: PropTypes.func.isRequired,
  };

  async handleIncrease(movie) {
    await this.props.increaseCount(movie, this.props.token);
  }

  async handleDelete(movie) {
    await this.props.deleteMovie(movie.id, this.props.token);
  }

  render() {
    return (
      <MovieList movies={this.props.movies}>
        {(text, movie) => (
          <div>
            <IncreaseCountButton
              onIncrease={() => this.handleIncrease(movie)}
              loading={this.props.isIncreasing(movie.id)}
            />
            <Divider type="vertical" />
            <DeleteButton
              onDelete={() => this.handleDelete(movie)}
              loading={this.props.isDeleting(movie.id)}
            />
          </div>
        )}
      </MovieList>
    );
  }
}

export const mapStateToProps = state => ({
  isIncreasing: id => getIsIncreasing(state, id),
  isDeleting: id => getIsDeleting(state, id),
});

export default connect(
  mapStateToProps,
  { deleteMovie, increaseCount }
)(MovieListContainer);

Мне кажется, что это может быть плохо по соображениям производительности / согласования, но я не уверен, как еще получить состояние способом, который скрывает детали реализации.

Суть ссылки: https://gist.github.com/vitalicwow/140c06a52dd9e2e062b2917f5c741727

Любая помощь приветствуется.

1 Ответ

0 голосов
/ 04 декабря 2018

Вот как вы можете справиться с этими асинхронными действиями с помощью приставки.Вы можете использовать thunk для выполнения 2 действий и сохранить флаг, чтобы определить, что делается с объектом (удаление, изменение и т. Д.):

действие

export const deleteMovieAction = id => {
  return dispatch => {
    dispatch({ type: "MOVIE_DELETING", id });
    setTimeout(() => {
      dispatch({ type: "MOVIE_DELETED", id });
    }, 2000);
  };
};

редуктор

const rootReducer = (state = initialState, action) => {
  switch (action.type) {
    case "MOVIE_DELETING": {
      const movies = [...state.movies];
      movies.find(x => x.id === action.id).isDeleting = true;
      return { ...state, movies };
    }
    case "MOVIE_DELETED": {
      const movies = state.movies.filter(x => x.id !== action.id);
      return { ...state, movies };
    }
    default:
      return state;
  }
};

https://codesandbox.io/s/k3jnv01ymv

Альтернативой является выделение идентификаторов в новый удаляемый массив

const rootReducer = (state = initialState, action) => {
  switch (action.type) {
    case "MOVIE_DELETING": {
      const movieDeletingIds = [...state.movieDeletingIds, action.id];
      return { ...state, movieDeletingIds };
    }
    case "MOVIE_DELETED": {
      const movieDeletingIds = state.movieDeletingIds.filter(
        x => x.id !== action.id
      );
      const movies = state.movies.filter(x => x.id !== action.id);
      return { ...state, movieDeletingIds, movies };
    }
    default:
      return state;
  }
};

https://codesandbox.io/s/mj52w4y3zj

(Этот код должен быть очищен, но только для демонстрации с использованием thunk)

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