개발노트

13. (2) useReducer 본문

React/basic

13. (2) useReducer

aloha2jh 2020. 7. 29. 00:30

클릭할때마다 어떤 tr의 td 누르고 있는지 알아내기

const Td = ()=>{ 
    const onClickTd = () =>{

    } 
    return(
        <td onclick={onClickTd}></td>
    )
}

(1) td를 클릭했을때니까  td에 onClick이벤트 추가.

함수니까useCallback으로 감싸기

 

 

(2)Table.jsx

{ Array(tableData.length).fill().map( ( tr ,i )=>( <Tr trIndex={i} trData={ tableData[i] }/> ) ) }

Table-> Tr컴포넌트로, row[] 하나씩 넘길때,

각row의 인덱스도 같이 넘겨줌

 

 

(3)Tr.jsx

Tr컴포넌트에서 (Tr->Td Props로)

위에서넘긴 row인덱스 받아서 넣고,

{ Array(trData.length).fill().map(( td ,i )=>( <Td trIndex={trIndex}  /> ) )}

td만들때 각 0,1,2인덱싱 추가

{ Array(trData.length).fill().map(( td ,i )=>( <Td trIndex={trIndex} tdIndex={i} /> ) )}

 

(5)Td.jsx

Td컴포넌트에서 rowIndex, dataIndex 받아서 처리.

import React ,{useCallback} from 'react';

const Td = ({trIndex, tdIndex})=>{  
    const onClickTd = useCallback(() =>{
        console.log( trIndex, tdIndex);
    },[]);

    return(
    <td onClick={onClickTd} >{trIndex+','+tdIndex}</td>
    )
};

export default Td;

클릭시 이렇게 콘솔에 찍힌다.

 

 

 

 

 

 

 

클릭했을때 td에 O 표시해주기

Td.jsx 

(1)state를바꾸는거 니까 action을만들어 dispatch(실행)시킨다.

 const onClickTd = useCallback(() =>{
     //console.log( trIndex, tdIndex);
     dispatch({ type:CLICK_TD, tr: trIndex, td: tdIndex });  /////
 },[]);

만든액션 - td를 클릭했다는 액션을만들고, 거기에 어떤tr의td인지 정보를 넣어줌!

 

 

Tictactoe

액션들을 처리하는 reducer 에서, 만든액션을 처리해준다

        case CLICK_TD :  {  //여기서 클릭한 tr,td에 해당하는 tableData 값을 바꿔줌
 
            const tableData = [...state.tableData ]; //(2)기존의 tableData 
            tableData[action.tr] = [...tableData[action.tr]]; //(3) action.tr이 지금바꾸려는tr.
            //그냥쓰지않고 펴?줘야 된다
            
            return{
                ...state
            }
        }

(2)기존의 배열복사. [ ['','',''],['','o',''],['','',''] ]

tableData [0][1][2] 에서 딱 바꾸려는 배열의 [v] 값만 바꾸기 위해

(3)action.tr로 선택 tableData[v]

??근데 여기서 바로쓰지 않고 펴줘야 된다고 한다. [...tableData[action.tr]]이렇게

 

tableData를 state에서복사해 왔으면서, 왜 또 tableData에서 해당하는 배열값을 복사해서 넣어주는건진 모르겠다;;

이게 단점?인데 에머emer라이브러리쓰면된다고한다..

 

 case CLICK_TD :  {   
            const tableData = [...state.tableData ];  
            tableData[action.tr] = [...tableData[action.tr]];  
            tabledata[action.tr][action.td] = state.turn;  //// (4)
            return{
                ...state,
                tableData,
            }
        }

(4)  arr[x][y] = 'o'  처리.

 

 

 

...해주는 이유는  tableData = state.tableData 해버리면 참조관계가 되기 때문에,

const a = { x:1 , y:2 };
const b = {...a }

const c = [1,2,3];
const d = [...c];

기존값 건들이지 않고, 복사 한다는 의미

 

 

turn바꾸는 action만들기

Td컴포넌트의 td onClick이벤트떄,

dispatch({type: CHANGE_TURN}); //o면x, x면o로 변경.

 

Tictactoe의  reducer

case CHANGE_TURN : {
            return{
                ...state,
                turn: state.turn === 'o'?'x':'o'
            }
        }

 

dispatch넘겨주기

Tictactoe -> Table -> Tr -> Td

이렇게 Td컴포넌트까지 dispatch를 넘겨준다.. (추후 context를 사용하자)

 

넘겨주는 이유는? dispatch함수로 Td컴포넌트에서 만든 action을 실행시켜야되는데,

Tictactoe컴포넌트에 dispatch 가 선언되있기 때문..

const Tictactoe = () =>{ 
   const [state, dispatch] = useReducer( reducer, initialState );
   ...
}

 

tableData값을 Td로 연결(넘겨주기)

'' ,'', '' 안의 (지금은 비어있는)값들과 Td컴포넌트에서 보여주도록 연결

 

//Table 컴포넌트
<Tr trData={ tableData[i] } />

//Tr 컴포넌트
<Td tdData = {trData[i] } />

이런식으로 넘겨줘서 .. 

 

 

이런식으로 잘 작동되는걸 확인가능...

'React > basic' 카테고리의 다른 글

14. context API  (0) 2020.07.29
13. (3) useReducer  (0) 2020.07.29
13. useReducer  (0) 2020.07.28
12. hooks / useEffect , useMemo  (0) 2020.07.28
12. componentDidUpdate , setInterval  (0) 2020.07.27