일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | |||||
3 | 4 | 5 | 6 | 7 | 8 | 9 |
10 | 11 | 12 | 13 | 14 | 15 | 16 |
17 | 18 | 19 | 20 | 21 | 22 | 23 |
24 | 25 | 26 | 27 | 28 | 29 | 30 |
- 리액트스타디
- 시퀄라이즈공부
- 시퀄라이즈
- mongoose
- sequelize
- React Component
- mongo
- 리액트기초
- 리액트
- 리액트컴포넌트
- nodeJS
- NPM
- component
- MongoDB
- express-generator
- NoSQL
- nodejs교과서
- 클래스컴포넌트
- node
- npm명령어
- 제로초예제
- React
- sementicversion
- Today
- Total
개발노트
14 (2)context API 본문
클릭했을때 TD를 계산해서 열어주는 액션
불변성을 유지하기 위해 딱 그 줄을 복사해서
그줄의 해당칸만 opened 로바꿔준다
Mine 컴포넌트에서 액션처리.
const reducer = (state,action)=>{
switch (action.type){
case OPEN_TD: ///
const tableData = [...state.tableData];
tableData[action.trIndex] = [...state.tableData[action.trIndex]];
tableData[action.trIndex][action.tdIndex] = TD_STATE.OPENED;
return{
...state,
tableData,
}
}
}
Td컴포넌트에서 액션dispatch(발생) 지금클릭한 tr, td 인덱스를 넘겨준다.
const Td = ({trIndex, tdIndex}) =>{
...
const onClickTd = useCallback(() =>{
dispatch({ type:OPEN_TD, trIndex, tdIndex });
},[]);
...
}
그러면 td 상태가 opend, 0으로 바뀌면서 스타일도 흰색으로 적용이 된다
칸들의 상태( 지뢰인지, 열린칸인지, 안열린그냥 칸인지)가 있고,
클릭시 상태에 따라 각각 다른 동작을 해줘야 되니까,
switch문으로 만들어서 인자로 상태를 받는다.
switch( tableData[trIndex][tdIndex] ){ //0, -1 ,-7 ...
case TD_STATE.NORMAL : //그냥칸이면(-1) -열리게
dispatch({ type:OPEN_TD, trIndex, tdIndex });
return;
case TD_STATE.MINE : //마인칸이면(-7) -open_mine액션
dispatch({ type:OPEN_MINE, trIndex, tdIndex });
return;
default : //이미열린칸, 깃발, 깃발-지뢰, 물음표, 물음표-지뢰 는-동작안하게
return;
}
오른쪽마우스 클릭 이벤트
우클릭 이벤트 잡아내기 위해 onContextMenu를 사용하면 된다
<td onClick={onClickTd} onContextMenu={onClick_RightTd}
(0) 브라우저기본메뉴안뜨게 e.preventDefault 부터 해줄것
const onClick_RightTd =(e)=>{
e.preventDefault(); //(0)
switch( tableData[trIndex][tdIndex] ){
case TD_STATE.NORMAL :
case TD_STATE.MINE : // 지뢰, 기본칸이면 깃발로만들어줌.
dispatch({ type:SET_FLAG, trIndex, tdIndex });
return;
case TD_STATE.FLAG_BUT:
case TD_STATE.FLAG:
dispatch({ type:SET_QUESTION, trIndex, tdIndex });
return;
case TD_STATE.QUESTION_BUT:
case TD_STATE.QUESTION:
dispatch({ type:SET_NORMAL, trIndex, tdIndex });
return;
}
}
기본,지뢰 칸 -> 깃발
깃발,깃발지뢰 칸 -> 물음표
물음표,물음표지뢰 칸 -> 기본칸
(임의의 액션들을 만들었음. SET_QUESTION, SET_NORMAL, SET_FLAG, OPEN_MINE )
reducer로 액션 처리
액션요청으로 TD_STATE상태값을 QUESTION으로 변경해주는 reducer.
case SET_QUESTION:{
const tableData = [...state.tableData];
tableData[action.trIndex] = [...state.tableData[action.trIndex]];
if( tableData[action.trIndex][action.tdIndex] === TD_STATE.MINE){ //지뢰칸이면
tableData[action.trIndex][action.tdIndex] = TD_STATE.QUESTION_BUT; //지뢰플래그
}else{
tableData[action.trIndex][action.tdIndex] = TD_STATE.QUESTION; //그냥플래그
}
return{
...state,
tableData,
}
}
우클릭을 했을때 지뢰칸이면 지뢰깃팔 칸인지, 그냥 깃발칸인지 구분해줘서 그렇지 간단한 코드
나머지 SET_NORMAL, SET_FLAG, OPEN_MINE도 동일
case SET_NORMAL:{
const tableData = [...state.tableData];
tableData[action.trIndex] = [...state.tableData[action.trIndex]];
if( tableData[action.trIndex][action.tdIndex] === TD_STATE.QUESTION_BUT){ //지뢰칸이면
tableData[action.trIndex][action.tdIndex] = TD_STATE.MINE; //지뢰플래그
}else{
tableData[action.trIndex][action.tdIndex] = TD_STATE.NORMAL; //그냥플래그
}
return{
...state,
tableData,
}
}
case SET_FLAG:{
const tableData = [...state.tableData];
tableData[action.trIndex] = [...state.tableData[action.trIndex]];
if( tableData[action.trIndex][action.tdIndex] === TD_STATE.MINE){ //지뢰칸이면
tableData[action.trIndex][action.tdIndex] = TD_STATE.FLAG_BUT; //지뢰플래그
}else{
tableData[action.trIndex][action.tdIndex] = TD_STATE.FLAG; //그냥플래그
}
return{
...state,
tableData,
}
}
OPEN_MINE의 경우 지뢰를 연것임으로 게임종료를 해줘야 되고,
export const TableContext = createContext({
tableData:[],
dispatch: () => {},
gameOver: true, //
});
const initialState = { //2
tableData:[],
timer:0,
result:0,
gameOver: true, //
}
gameOver: false 를 initialState와 context에도 새로 추가 한다
const Mine = () =>{
...
const { timer , result , tableData, gameOver } = state;
const tblContextValue = useMemo( ()=>({ tableData, dispatch , gameOver }) ,[tableData]);
...
}
보내는 값에도 추가해준다.
지뢰클릭시 클릭안되게
그래서 Tr 컴포넌트에서 context에서 추가해준 gameOver값을 꺼내오고
onClickTd 칸 클릭이벤트때 gameOver T 면 return시킨다.
useCallback 을 사용했으니 (gameOver바뀌는 값이고) 의존성배열에도 추가해줘야 됨
const onClickTd = useCallback(() =>{
if(gameOver){
return;
}
...
}
//우클릭 이벤트도 마찬가지
const onClick_RightTd =(e)=>{
e.preventDefault();
if(gameOver){
return;
}
...
}
초기값이 false니까, GAME_START액션 처리해주는 reducer에서 상태값 true로 꼭 바꿔준다~
case START_GAME:
return{
...state,
tableData: plantMine(action.row, action.col, action.mine),
gameOver: false,
};
'React > basic' 카테고리의 다른 글
14. (4)context API (0) | 2020.07.31 |
---|---|
14 (3)context API (0) | 2020.07.30 |
14. context API (0) | 2020.07.29 |
13. (3) useReducer (0) | 2020.07.29 |
13. (2) useReducer (0) | 2020.07.29 |