存储所有响应数据

时间:2018-09-03 11:50:26

标签: reactjs redux

我正在尝试开发一个应用程序,该应用程序显示未飞溅的照片,然后将这些照片渲染到该应用程序。由于必须对结果进行排序并调用第二个端点,因此我使用的是redux-thunk。我需要将先前的搜索存储在变量中,然后能够显示特定关键字的数据,而无需发送第二个API请求。

我阻止了SearchBar组件中的第二个API调用:

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,但是,这似乎也是错误的。

0 个答案:

没有答案