1
votes

Currently I want to dispatch the action inside the async function, but the action is not being dispatched? The reason for using Redux is because I want to add a like button to any images that is being filtered by the search input.

The link to the entire App am working on.... ---go to file components/App.js

import React from 'react';
import SearchBar from './SearchBar';
import unsplash from '../api/unsplash';
import ImageList from './ImageList';
import { fetchImages } from '../actions';
import { connect } from 'react-redux';

class App extends React.Component {
  state = { images: [] };

  onSearchSubmit = term => {  

    return async (dispatch) => {

      const response = await unsplash.get('/search/photos', {
        params:{ query: term },
        //use the path on unsplash for image searching
      })

      let success = response.data.results
      
      dispatch(fetchImages(success));
      return success;
      // this.setState({ images: response.data.results });
    }
    
  }

  render() {
    return (<div className="ui container" style={{marginTop:'10px'}}> 
      <SearchBar onSubmit={this.onSearchSubmit}/>
      <ImageList images={this.state.images}/>
    </div>);
  }
}

const mapDispatchToProps = (dispatch) => ({

    fetchImages: images => dispatch(fetchImages(images))

})

export default connect(null, mapDispatchToProps)(App);
3
dispatch is not magic keyword, you would have to pass dispatch to your App or your function inside your App component onSearchSubmit so that it holds reference to dispatch using which you can dispatch actions in there. - Rikin
Maybe you can check the added link which redirect you to codesandbox if you click on that. @Rikin - Fresh developer

3 Answers

0
votes

I'm take more updates on your project. see codesandbox example!

import React from "react";
import SearchBar from "./SearchBar";
import ImageList from "./ImageList";
import { fetchImages } from "../actions";
import { connect } from "react-redux";
import { bindActionCreators } from "redux";

class App extends React.Component {

  onSearchSubmit = term => {
    this.props.fetchImages(term);
  };

  render() {
    return (
      <div className="ui container" style={{ marginTop: "10px" }}>
        <SearchBar onSubmit={this.onSearchSubmit} />
        <ImageList images={this.props.images} />
      </div>
    );
  }
}

export default connect(
  state => ({
    images: state.images
  }),
  dispatch => ({
    fetchImages: bindActionCreators(fetchImages, dispatch)
  })
)(App);

Action:

export function fetchImages(term) {
  return function action(dispatch, getState) {
    unsplash
      .get("/search/photos", {
        params: { query: term }
        //use the path on unsplash for image searching
      })
      .then(res => {
        console.log(res.data.results);
        dispatch({ type: types.FETCH_BUTTON, payload: res.data.results });
      });
  };
}

And state:

export const images = (state = [], action) => {
  switch (action.type) {
    // ...
    case types.FETCH_BUTTON:
      return Object.assign([], state, [...action.payload]);
    default:
      return state;
  }
};

Working example:

Edit angry-zhukovsky-j9qv1

0
votes

Modifing @Fiodorov Andrei code a little.

Here is a way without bindActionCreators.

Just define function in mapDispatchToProps as "onSearchSubmit" and dispatch action there (simple one liner :) )


import React from "react";
import SearchBar from "./SearchBar";
import ImageList from "./ImageList";
import { fetchImages } from "../actions";
import { connect } from "react-redux";

class App extends React.Component {
  state = { images: [] };

  render() {
    const { onSearchSubmit } = this.props;

    return (
      <div className="ui container" style={{ marginTop: "10px" }}>
        <SearchBar onSubmit={onSearchSubmit} />
        <ImageList images={this.props.images} />
      </div>
    );
  }
}

export default connect(
  state => ({
    images: state.images
  }),
  dispatch => ({
    onSearchSubmit: term => dispatch(fetchImages(term)),
  })
)(App);

codesandbox

-1
votes

You already mapped dispatch to your props and do not need to call dispatch(fetchImages()). Try to call that mapped function instead:
this.props.fetchImages()