[오즈의 제작소 NINJA] 21/05/26
react-query
공부하기
context API
셋팅하기
기본 개념
// FactoryTable Component
// Context를 만드는 코드
export const TableContext = createContext({ data: '123' });
const FactoryTable = () => (
// Context를 하위 컴포넌트들에 뿌려주는 Provider 컴포넌트
<TableContext.Provider value={{ data: '1234' }}>
<Wrapper>
<CategoryListWrapper>
<CategoryList category={category} />
</CategoryListWrapper>
<TableWrapper>
<KindsTableWrapper>
<KindsTable kinds={Kinds} />
</KindsTableWrapper>
<FactoryItemsTable />
</TableWrapper>
</Wrapper>
</TableContext.Provider>
);
TableContext.Provider
의 내부를 보면 children
으로 하위 컴포넌트들을 받고, Provider
컴포넌트에서 받는 밸류로 로직 정해서 내보내주지 않을까 생각.
다음과 같이 사용한다.
const CategoryList: React.FC<ICategoryListProps> = ({ category }) => {
// useContext 훅으로 Context 넣어주면 그 Context가 갖고 있는 스테이트 리턴함.
const context = useContext(TableContext);
console.log(context);
const [isFocus, setIsFocus] = useState<string | null>('');
const onClick = (e: React.MouseEvent<HTMLElement>) => {
setIsFocus((e.target as HTMLElement).textContent);
};
return (
<Wrapper onClick={onClick}>
{category.map(item => (
<Item focus={isFocus === item.name} key={item.id}>
{item.name}
</Item>
))}
</Wrapper>
);
};
React Router
//App.tsx
<Switch>
<Route path={routes.home} exact>
Hello
</Route>
<Route path={routes.factoryList} exact component={FactoryListPage} />
// exact가 빠져있는 경우
<Route path={routes.factoryDetail} component={FactoryDetailPage} />
<Route path={routes.factoryEdit} exact component={FactoryEditPage} />
<Route path={routes.factoryRepresentEdit} exact component={FactoryRepresentEditPage} />
<Route>NotFound</Route>
</Switch>
//App.tsx
<Switch>
<Route path={routes.home} exact>
Hello
</Route>
<Route path={routes.factoryList} exact component={FactoryListPage} />
// exact가 빠져있는 경우
<Route path={routes.factoryDetail} component={FactoryDetailPage} />
<Route path={routes.factoryEdit} exact component={FactoryEditPage} />
<Route path={routes.factoryRepresentEdit} exact component={FactoryRepresentEditPage} />
<Route>NotFound</Route>
</Switch>
routes.factoryDetail
routes.factoryEdit
의 라우터가 routes.factoryDetail
로 올 수 있다.
/:id/123 | /:id/123/repe
같은 라우터 들이 /:id
로 올 수 있음
그렇기에 다음과 같이 exact
속성을 부여해야한다.
<Route path={routes.factoryDetail} exact component={FactoryDetailPage} />
interface vs type
interface 는 객체밖에 안돼
import React, { createContext, Dispatch, useReducer } from 'react';
interface ITableAction {
type: 'CREATE' | 'TOGGLE';
payload: string | number | undefined;
}
interface ITableState {
// 품목 객체
// 품목 객체 안에 종류 객체
// 종류 객체 안에는 상품 배열이 있다.
test: number;
}
interface ITableDispatch {
dispatch: Dispatch<ITableAction>;
}
const TableContext = createContext<ITableState | undefined>(undefined);
const TableDispatchContext = createContext<ITableDispatch | undefined>(undefined);
const initialTableState = {
test: 0,
};
function tableReducer(state: ITableState, action: ITableAction): ITableState {
switch (action.type) {
case 'CREATE':
return { test: 1 };
case 'TOGGLE':
return { test: 2 };
default:
throw new Error('없는 액션');
}
}
export function TableContextProvider({ children }: { children: React.ReactNode }) {
const [tableState, dispatch] = useReducer(tableReducer, initialTableState);
return (
<TableContext.Provider value={tableState}>
// TableDispatchContext는 ITableDispatch 인터페이스로 정해진 Context이다. value에 들어가는 값이 ITableDispatch 인터페이스 타입이어야하는데, dispatch 속성을 가진 객체로 인터페이스를 지정했으므로 다음과 같이 넣어주어야함.
<TableDispatchContext.Provider value={{ dispatch }}>{children}</TableDispatchContext.Provider>
</TableContext.Provider>
);
}
import React, { createContext, Dispatch, useReducer } from 'react';
interface ITableAction {
type: 'CREATE' | 'TOGGLE';
payload: string | number | undefined;
}
interface ITableState {
// 품목 객체
// 품목 객체 안에 종류 객체
// 종류 객체 안에는 상품 배열이 있다.
test: number;
}
interface ITableDispatch {
dispatch: Dispatch<ITableAction>;
}
const TableContext = createContext<ITableState | undefined>(undefined);
const TableDispatchContext = createContext<ITableDispatch | undefined>(undefined);
const initialTableState = {
test: 0,
};
function tableReducer(state: ITableState, action: ITableAction): ITableState {
switch (action.type) {
case 'CREATE':
return { test: 1 };
case 'TOGGLE':
return { test: 2 };
default:
throw new Error('없는 액션');
}
}
export function TableContextProvider({ children }: { children: React.ReactNode }) {
const [tableState, dispatch] = useReducer(tableReducer, initialTableState);
return (
<TableContext.Provider value={tableState}>
// TableDispatchContext는 ITableDispatch 인터페이스로 정해진 Context이다. value에 들어가는 값이 ITableDispatch 인터페이스 타입이어야하는데, dispatch 속성을 가진 객체로 인터페이스를 지정했으므로 다음과 같이 넣어주어야함.
<TableDispatchContext.Provider value={{ dispatch }}>{children}</TableDispatchContext.Provider>
</TableContext.Provider>
);
}
value = {dispatch}
로 하고싶다면
import React, { createContext, Dispatch, useReducer } from 'react';
interface ITableAction {
type: 'CREATE' | 'TOGGLE';
payload: string | number | undefined;
}
interface ITableState {
// 품목 객체
// 품목 객체 안에 종류 객체
// 종류 객체 안에는 상품 배열이 있다.
test: number;
}
type ITableDispatch = Dispatch<ITableAction>;
const TableContext = createContext<ITableState | undefined>(undefined);
const TableDispatchContext = createContext<ITableDispatch | undefined>(undefined);
const initialTableState = {
test: 0,
};
function tableReducer(state: ITableState, action: ITableAction): ITableState {
switch (action.type) {
case 'CREATE':
return { test: 1 };
case 'TOGGLE':
return { test: 2 };
default:
throw new Error('없는 액션');
}
}
export function TableContextProvider({ children }: { children: React.ReactNode }) {
const [tableState, dispatch] = useReducer(tableReducer, initialTableState);
return (
<TableContext.Provider value={tableState}>
<TableDispatchContext.Provider value={dispatch}>{children}</TableDispatchContext.Provider>
</TableContext.Provider>
);
}
event type
onclick
으로 이벤트 객체 받는 경우
const handleSubmit = (e: React.FormEvent<HTMLFormElement>) => {
// 여기도 모르니까 any 로 하겠습니다.
e.preventDefault();
onSubmit(form);
setForm({
name: '',
description: ''
}); // 초기화
};
onclick
으로 이벤트 객체 받는 경우 const handleSubmit = (e: React.FormEvent<HTMLFormElement>) => {
// 여기도 모르니까 any 로 하겠습니다.
e.preventDefault();
onSubmit(form);
setForm({
name: '',
description: ''
}); // 초기화
};
e
객체에다 타입을 명시해주어야함.
// TextCell.tsx
const TextCell: React.FC<ITextCellProps> = ({ content, ...style }) => {
const onClick = (e: React.MouseEvent<HTMLDivElement>) => {
console.log('cell click');
console.log(e.target);
// 모달 스테이트 만들어서 TextModal isOpen함
};
return (
<Cell {...style} onClick={onClick}>
<Wrapper>{content}</Wrapper>
</Cell>
);
};
주의 : React.MouseEventHandler<HTMLDivElement>
와 헷갈려서는 안된다. Handler
타입은 함수타입임
허나, 타입을 위 코드처럼 명시하여도 target
아래 속성들에는 접근할 수 없다.
어떤 타입을 명시해야 target
아래 속성들에 접근할 수 있을까
디자인 이슈
- 다음 사진 처럼 벌어지는 이유
font-size: 11px;
font-size: 11px;
폰트 사이즈가 해시태그 셀 부분만 작았다. 그렇기에 요소의 크기가 다른 셀 크기보다 작게됨. (통일 되지 못하게댐)
폰트사이즈 부분 지우
다음과 같이 생기던 균열이 없어지게됨.
Reference
Author And Source
이 문제에 관하여([오즈의 제작소 NINJA] 21/05/26), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다
https://velog.io/@rat8397/오즈의-제작소-NINJA-210526
저자 귀속: 원작자 정보가 원작자 URL에 포함되어 있으며 저작권은 원작자 소유입니다.
우수한 개발자 콘텐츠 발견에 전념
(Collection and Share based on the CC Protocol.)
Author And Source
이 문제에 관하여([오즈의 제작소 NINJA] 21/05/26), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://velog.io/@rat8397/오즈의-제작소-NINJA-210526저자 귀속: 원작자 정보가 원작자 URL에 포함되어 있으며 저작권은 원작자 소유입니다.
우수한 개발자 콘텐츠 발견에 전념 (Collection and Share based on the CC Protocol.)