redux-thunk로 rn -firebase 관리하기

리리·2021년 8월 10일

TIL

목록 보기
18/22

app.js

// import 추가
import ReduxThunk from 'redux-thunk';
import { applyMiddleware } from 'redux';

//추가부분
const store = createStore(rootReducer, applyMiddleware(ReduxThunk));

store/action/product.js

export const SET_PRODUCTS = 'SET_PRODUCTS';

export const fetchProducts = () => {
  return async  dispatch => {
    // any async code you want
    const response = await fetch('https://udemy-shopping-68f57-default-rtdb.firebaseio.com/products.json');

    const resData = await response.json();
    const loadedProducts = [];

    for (const key in resData) {
      loadedProducts.push(
        new Product(
          key,
          'u1',
          resData[key].title,
          resData[key].imageUrl,
          resData[key].description,
          resData[key].price
        )
      );
    }
    dispatch({type: SET_PRODUCTS, products : loadedProducts});
  };
};

export const createProduct = (title, description, imageUrl, price) => {

  return async dispatch => {
    // any async code you want
    const response = await fetch('https://udemy-shopping-68f57-default-rtdb.firebaseio.com/products.json', {
      method: 'POST',
      headers: {
        'Content-Type': 'application/json'
      },
      body: JSON.stringify({
        title,
        description,
        imageUrl,
        price
      })
    });

    const resData = await response.json();

    console.log(resData);

    dispatch({
      type: CREATE_PRODUCT,
      productData: {
        id: resData.name,
        title,
        description,
        imageUrl,
        price
      }
    });
  }
};

store/reducers/product.js

import {
  DELETE_PRODUCT,
  CREATE_PRODUCT,
  UPDATE_PRODUCT,
  SET_PRODUCTS //추가
} from '../actions/products';

export default (state = initialState, action) => {
  switch (action.type) {
  //추가
    case SET_PRODUCTS:
      return {
        availableProducts: action.products,
        userProducts: action.products.filter(prod => prod.ownerId === 'u1')
      };

shop/ProductsOverviewScreen.js

// 추가
import React, { useEffect, useState, useCallback } from 'react';

const ProductsOverviewScreen = props => {
// 추가
  const [isLoading, setIsLoading] = useState(false);
  const [error, setError] = useState();

// 상품 페이지에서 매번 로드되도록 callback 함수 사용

  const loadProducts = useCallback (async () => {
    setError(null);
    setIsLoading(true);
    try {
      await dispatch(productsActions.fetchProducts());
    } catch (err) {
      setError(err.message);
    }
    setIsLoading(false);
  }, [dispatch, setIsLoading, setError]);

  useEffect(() => {
    const willFocusSub = props.navigation.addListener('willFocus', loadProducts);

    // cleanup function
    return () => {
      willFocusSub.remove();
    };
  }, [loadProducts]);

  // useEffect(() => {
  //   loadProducts();
  // }, [dispatch, loadProducts]);

  if (error) {
    return <View style={styles.centered}>
      <Text>Error occured.</Text>
      <Button title="Try Again" onPress={loadProducts} color={Colors.primary} />
    </View>;
  }
  if (isLoading) {
    return <View style={styles.centered}>
      <ActivityIndicator size='large' color={Colors.primary} />
    </View>;
  };

  if (!isLoading && products.length === 0) {
    return <View style={styles.centered}>
      <Text>No products found. Start add some.</Text>
    </View>;

  };

0개의 댓글