Хранение всех данных ответов - PullRequest
0 голосов
/ 03 сентября 2018

Я пытаюсь разработать приложение, которое показывает фотографии с unsplash, которые затем отображаются в приложении. Поскольку я должен был отсортировать результаты и вызвать вторую конечную точку, я использую Redux-Thunk. Мне нужно сохранить предыдущие поиски в переменной, а затем иметь возможность отображать данные для определенного ключевого слова, не отправляя второй запрос API.

Я запрещаю второй вызов API в моем компоненте SearchBar:

class SearchBar extends Component {
  constructor(props) {
    super(props);
    this.state = {
      term: ""
    };

    this.onInputChange = this.onInputChange.bind(this);
    this.onFormSubmit = this.onFormSubmit.bind(this);
  }

  onInputChange(event) {
    this.setState({
      term: event.target.value
    });
  }

  onFormSubmit(event) {
    event.preventDefault();
    const { categories } = this.props;

    if (!categories.includes(this.state.term.toLowerCase())) {
      this.props.setCategory(this.state.term);
      this.props.fetchPhotos(this.state.term);
    } else {
      alert(`You've already searched for ${this.state.term.toLowerCase()}`);
    }

    this.setState({
      term: ""
    });
  }

  render() {
    return (
      <form onSubmit={this.onFormSubmit}>
        <input
          placeholder="Type your request"
          className="form-control"
          value={this.state.term}
          onChange={this.onInputChange}
        />
      </form>
    );
  }
}

const mapDispatchToProps = dispatch => {
  return bindActionCreators({ fetchPhotos, setCategory }, dispatch);
};

const mapStateToProps = state => {
  return {
    categories: state.categories
  }
}

export default connect(
  mapStateToProps,
  mapDispatchToProps
)(SearchBar);

Однако, поскольку я использую асинхронные действия, у меня возникают проблемы с хранением данных.

Создатели действий:

const unsplashClient = new Unsplash({
  applicationId:
    "id",
  secret: "secret",
  callbackUrl: "callback"
});

export const fetchingPhotos = payload => ({
  type: FETCHING_PHOTOS,
  payload
});

export const setPhotos = payload => ({
  type: SET_PHOTOS,
  payload
});

export const fetchPhotos = term => dispatch => {
  dispatch(fetchingPhotos());
  return unsplashClient.search
    .photos(term, 1, 20)
    .then(toJson)
    .then(json => {
      dispatch(setPhotos(json));
      dispatch(fetchingPhotos(false));
    });
};

export const unsplash = term => dispatch => {
  dispatch(fetchingPhotos());

  setTimeout(() => {
    dispatch(fetchPhotos(term));
    return Promise.resolve();
  }, 1000);
};

Разбавление:

export default function(state = initialState, action) {
  switch (action.type) {
    case FETCHING_PHOTOS:
      return {
        ...state,
        isFetching: true
      };
    case SET_PHOTOS:
      console.log(action, state);
      return {
        ...state,
        isFetching: false,
        items: action.payload.results,
        store: Object.assign({}, state, action.payload.results)
      };
    case SET_SORT:
      return {
        ...state,
        sortKey: action.sortKey,
        sortDirection: action.sortDirection
      };
    default:
      return state;
  }
}

И компонент, который получает данные:

class PhotoList extends Component {
  constructor(props) {
    super(props);
    this.state = {
      sortKey: "",
      sortDirection: "descending"
    };

    this.handleClick = this.handleClick.bind(this);
    this.handleKeyChange = this.handleKeyChange.bind(this);
    this.handleDirectionChange = this.handleDirectionChange.bind(this);
  }

  renderPhotos() {
    console.log(this.props);

    const { items: photos } = this.props;

    if (!photos) {
      return;
    }

    return photos.map(photo => {
      const url = photo.urls.small;
      const id = photo.id;

      const alt = photo.description;
      return <SinglePhoto url={url} key={id} id={id} alt={alt} />;
    });
  }

  handleClick() {
    const { dispatch } = this.props;
    const { sortDirection, sortKey } = this.state;
    dispatch(sort(sortDirection, sortKey));
  }

  handleKeyChange(e) {
    this.setState({
      ...this.state,
      sortKey: e.target.value
    });
  }

  handleDirectionChange(e) {
    this.setState({
      ...this.state,
      sortDirection: e.target.value
    });
  }

  render() {
    return (
      <div>
        <div>
          <div>
            <label htmlFor="sortKey">Sort Key:</label>
            <select
              name="sortKey"
              id="sortKey"
              value={this.state.sortKey}
              onChange={this.handleKeyChange}
            >
              <option value="">Select property</option>
              <option value="created_at">created_at</option>
              <option value="likes">likes</option>
              <option value="downloads">downloads</option>
            </select>
          </div>
          <label htmlFor="sortDirection">Sort Direction:</label>
          <select
            name="sortDirection"
            id="sortDirection"
            value={this.state.sortDirection}
            onChange={this.handleDirectionChange}
          >
            <option value="descending">Descending</option>
            <option value="ascending">Ascending</option>
          </select>
          <button type="button" onClick={this.handleClick}>
            SORT
          </button>
        </div>
        <div className="grid">{this.renderPhotos()}</div>
      </div>
    );
  }
}

const mapStateToProps = state => {
  return {
    items: getSortedPhotosSelector(state),
    sortKey: state.photos.sortKey,
    sortDirection: state.photos.sortDirection,
    store: state.store
  };
};

export default connect(mapStateToProps)(PhotoList);

Метод Object.assign(), к сожалению, не работает должным образом: я думал, что он будет хранить все искомые данные, а не только текущий искомый.

Как я могу хранить данные и иметь доступ к ним позже? Моей первой мыслью было использовать localStorage, однако, это также кажется неправильным.

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