[오즈의 제작소 NINJA] 21/05/28

16210 단어 projectproject

switch case lexical scope

프로덕트 수정

프로덕트의 텍스트 내용을 수정하면

    dispatch({ type: 'CHANGE_TEXT_MODAL_VALUE', payload: { newValue: tempCurrentProduct } });

의 액션을 수행.

currentProduct의 내용을 수정하고, reducer로 보내서

reducer에서 products을 순회하며 currentProduct와 일치하는 product를 바꿈

상태 저장.

useEffect 이슈

/factory/1에서 안보이는 이슈

 useEffect(() => {
    if (data && categoryData) {
      const hashtags: any = {};
      const allKinds: any = {};
      const { category } = categoryData;
      Object.keys(category).forEach(item =>
        category[item].Kinds.forEach((kind: any) => {
          allKinds[kind.name] = kind.id;
          hashtags[kind.name] = kind.Hashtags;
        })
      );
      const { groupedProducts, items, kinds } = makeGroup(data.productOfFactory);
      dispatch({
        type: 'INIT_TABLE',
        payload: {
          allProducts: groupedProducts,
          allItems: items,
          allKinds: kinds,
          // 내가 만든거 밑에
          allHashtags: hashtags,
          allKindsById: allKinds,
        },
      });
    }
  }, [data, categoryData]);

Context API Reducer

action이 오면 첫 라인부터 쭉 순서대로 수행. 잊지말자 헷갈리면안된다.

import { TableActionType, TableStateType } from '@/contexts/FactoryTableContext/types';

export function tableReducer(state: TableStateType, action: TableActionType): TableStateType {
  let currentItem: string;
  let currentKind: string;
  let items: Array<string>;
  let kinds: Array<string>;
  let products: any;
  let currentProducts: any;

  switch (action.type) {
    case 'OPEN_MODAL':
      return {
        ...state,
        modal: { ...state.modal, ...action.payload },
      };
    /* products(배열)=>currentProducts(객체)로 변경하였음. */
    case 'INIT_TABLE':
      [currentItem] = Object.keys(action.payload.allProducts); // first element of items
      kinds = Object.keys(action.payload.allProducts[currentItem]);
      [currentKind] = kinds; // first element of kinds
      currentProducts = {};
      action.payload.allProducts[currentItem][currentKind].forEach((product: any) => {
        currentProducts[`${product.id}`] = product;
      });
      return {
        ...state,
        factory: {
          ...state.factory,
          ...action.payload,
        },
        table: {
          ...state.table,
          kinds,
          currentItem,
          currentKind,
          allHashtags: { ...state.table.allHashtags, ...action.payload.allHashtags },
          allKindsById: { ...state.table.allKindsById, ...action.payload.allKindsById },
          currentProducts,
        },
      };

    case 'CHANGE_CURRENT_ITEM':
      kinds = Object.keys(state.factory.allProducts[action.payload.currentItem]);
      [currentKind] = kinds; // first element of kinds
      console.log(currentProducts);
      currentProducts = {};
      state.factory.allProducts[action.payload.currentItem][currentKind].forEach((product: any) => {
        currentProducts[`${product.id}`] = product;
      });
      return {
        ...state,
        table: {
          ...state.table,
          ...action.payload,
          kinds,
          currentKind,
          currentProducts,
        },
      };

    case 'CHANGE_CURRENT_KIND':
      currentProducts = {};
      state.factory.allProducts[state.table.currentItem][action.payload.currentKind].forEach(
        (product: any) => {
          currentProducts[`${product.id}`] = product;
        }
      );
      return {
        ...state,
        table: {
          ...state.table,
          ...action.payload,
          currentProducts,
        },
      };
    /* 로우 추가버튼. 상품 테이블에 로우하나 추가된다. */
    case 'ADD_EMPTY_PRODUCT':
      return {
        ...state,
        table: {
          ...state.table,
          currentProducts: {
            ...state.table.currentProducts,
            [action.payload.newValue.id]: action.payload.newValue,
          },
          isModifed: { ...state.table.isModifed, [action.payload.newValue.id]: true },
        },
      };
    /* 프로덕트 셀(텍스트 셀,이미지 셀,해시태그 셀) 데이터 변경되면 반영함 */

    case 'CHANGE_PRODUCT_CELL':
      return {
        ...state,
        table: {
          ...state.table,
          currentProducts: {
            ...state.table.currentProducts,
            [action.payload.newValue.id]: action.payload.newValue,
          },
          isModifed: { ...state.table.isModifed, [action.payload.newValue.id]: true },
        },
      };
    /* 수정 클릭하면 클릭한 상품의 수정 버튼 사라져야함 */
    /* 셀 데이터들은 이미 CHANGE PRODUCT CELL 액션으로 수정되어있음 */

    case 'UPDATE_PRODUCT':
      return {
        ...state,
        table: {
          ...state.table,
          isModifed: {
            [action.payload.productId]: false,
          },
        },
      };
    /* 삭제 클릭하면 클릭한 상품 없어짐 */

    case 'DELETE_PRODUCT':
      currentProducts = state.table.currentProducts;
      delete currentProducts[action.payload.productId];
      return {
        ...state,
        table: {
          ...state.table,
          currentProducts: {
            ...currentProducts,
          },
        },
      };
    /* 클릭하면 상태가 가리키는 현재 상품 바뀜 */
    case 'CHANGE_CURRENT_PRODUCT':
      return {
        ...state,
        modal: {
          ...state.modal,
          currentProduct: action.payload.currentProduct,
        },
      };

    case 'ADD_KIND':
      items = Object.keys(action.payload.selectKind);
      kinds = Object.keys(action.payload.selectKind)
        .map((item: string) => action.payload.selectKind[item].map((kind: string) => kind))
        .reduce((acc, cur) => acc.concat(cur), []);

      products = {};
      Object.keys(action.payload.selectKind).forEach((item: string) => {
        products[item] = {};
        action.payload.selectKind[item].forEach((kind: string) => {
          if (
            state.factory.allItems.some((ai: string) => ai === item) &&
            state.factory.allKinds.some((ak: string) => ak === kind)
          ) {
            products[item][kind] = state.factory.allProducts[item][kind];
          } else {
            products[item][kind] = [];
          }
        });
      });

      return {
        ...state,
        factory: {
          ...state.factory,
          allItems: items,
          allKinds: kinds,
          allProducts: products,
        },
        table: {
          ...state.table,
          currentItem: action.payload.currentItem,
          kinds: products[action.payload.currentItem]
            ? Object.keys(products[action.payload.currentItem])
            : [],
        },
      };
    default:
      throw new Error('없는 액션');
  }
}

div onClick Function Error

<div key={key} data-id={`${product.id}`} onClick={onClickRow} role="button" tabIndex={index}>

자꾸 롤을 추가하라는 에러가 발생함.

role에 명시한 후 tabIndexindex값을 넣어주자

tabIndex

탭같은걸로 포커스를 지정할 수 있다. 레퍼런스 볼것

as Type

const onClickCell = ({ e, type }: TOnClickCellProps) => {
  // type을 TOnClickCellProps로 정의하여 string => 특정 타입으로 제한할 수 있다.
    const columnString = (e.currentTarget as HTMLDivElement).dataset.column as ColumnStringType;
  
  // ColumnString을 string => 특정 값만 가지도록 제한해야
    const { offsetTop: top, offsetLeft: left } = e.currentTarget as HTMLDivElement;

    dispatch({
      type: 'OPEN_MODAL',
      payload: {
        type,
        // 여기다 대입할 수 있다.
        position: { top, left },
        columnString: columnString || '',
        // 여기다 대입할 수 있다.
      },
    });
    setIsActive(true);
  };

Reference

좋은 웹페이지 즐겨찾기