Associate images with post in ReactJS

巧了我就是萌 提交于 2020-08-09 13:34:06

问题


Here's an action that return a post list and the images inside each post. Previously, this action was only returning the post list. How to adapt the reducer and the component to associate which images belongs to which post?

Action

export const recipesListFetch = (page = 1) => {
   return (dispatch) => {
      dispatch(recipesListRequest());
      return requests
         .get(`/recipes?_page=${page}`)
         .then(async (response) => {
            const recipes = response["hydra:member"];
            const imagesForRecipe = [];
            for (let i = 0; i < recipes.length; i++) {
            for (let j = 0; j < recipes[i].image.length; j++) {
               const imageUrlProperty = recipes[i].image[j];
               const image = await requests.get(`${imageUrl}`);

               imagesForRecipe.push(image);
            }
            recipes[i].image = imagesForRecipe;
            }
            dispatch(recipesListReceived(response));
         })
         .catch((error) => dispatch(recipesListError(error)));
   };
};

Reducer

export default(state = {
   posts: null,
   isFetching: false,
   currentPage: 1,
   pageCount: null
}, action) => {
   switch (action.type) {
      case RECIPES_LIST_REQUEST:
         state = {
            ...state,
            isFetching: true,
         };
         return state;
      case RECIPES_LIST_RECEIVED:
         state = {
            ...state,
            posts: action.data['hydra:member'],
            pageCount: hydraPageCount(action.data),
            isFetching: false,
         };
         return state;
      case RECIPES_LIST_ERROR:
         return {
            ...state,
            isFetching: false,
            posts: null,
         };
      case RECIPES_LIST_ADD:
         state = {
            ...state,
            posts: state.posts ? state.posts.concat(action.data) : state.posts
         };
         return state;
      case RECIPES_LIST_SET_PAGE:
         return {
            ...state,
            currentPage: action.page
         };
      default:
         return state;
   }
}

Component

class RecipesList extends React.Component {

   render() {
      const {posts} = this.props;
      if (null === posts || 0 === posts.length) {
         return (<Message message="Aucune recette trouvé"/>);
      }

      return (
         <div className="container-fluid padding pt-5 responsive-card">
            <div className="row padding">
               {posts && posts.map(post => (
                  <div className="col-md-6 col-lg-3 add-padding" key={post.id}>
                     <Link to={`/recipes/${post.id}`}>
                        <div className="card mb-3 mt-3" >
                        <img src={???} alt="" className="img-recipe-list"/>
                           <div className="card-body">
                              <h3>{post.title}</h3>
                              <p className="card-text d-flex justify-content-center">
                                 <small className="text-muted">{post.time}</small>
                              </p>
                           </div>
                        </div>
                     </Link>
                  </div>
               ))}
            </div>
         </div>
      )
   }
}

export default RecipesList;

I would like to render a card for each post with the image and the title of the post.


回答1:


The first issue i am seeing is that you are not returning the imagesForRecipe, instead you are returning the response.

export const recipesListFetch = (page = 1) => {
   return (dispatch) => {
      dispatch(recipesListRequest());
      return requests
         .get(`/recipes?_page=${page}`)
         .then(async (response) => {
            // i strongly advice to not mutate the response object
            // im not sure how your request method works, but if response is immutable
            // your recipes will never actually get added
            // to prevent that you can dispatch a new object instead of the response
      
            const recipes = response["hydra:member"];

            for (let i = 0; i < recipes.length; i++) {
              // move this into the first for loop, becuase you want to start with 
              // an empty array for every recipe
              const imagesForRecipe = [];

              for (let j = 0; j < recipes[i].image.length; j++) {
               const imageUrlProperty = recipes[i].image[j];
               const image = await requests.get(`${imageUrl}`);

               imagesForRecipe.push(image);
              }
              // here you assign only the images for a specific recipe
              recipes[i].image = imagesForRecipe;
            }
            // return a new object with updated recipes
            const editedResponse = { ...response, "hydra:member": recipes };

            dispatch(recipesListReceived(editedResponse));
         })
         .catch((error) => dispatch(recipesListError(error)));
   };
};

I hope this helps :)



来源:https://stackoverflow.com/questions/62769213/associate-images-with-post-in-reactjs

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!