일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
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 |
- 시퀄라이즈
- component
- React
- npm명령어
- 제로초예제
- nodeJS
- 리액트기초
- NPM
- 리액트
- sementicversion
- 리액트스타디
- nodejs교과서
- React Component
- sequelize
- NoSQL
- 클래스컴포넌트
- express-generator
- 리액트컴포넌트
- 시퀄라이즈공부
- node
- mongoose
- mongo
- MongoDB
- Today
- Total
개발노트
13. useReducer 본문
틱택토(삼목게임) 만들기
TicTacToe > Table > Tr > Td
const Tictactoe = () =>{
const [winner, setWinner] = useState('');
const [turn, setTurn] = useState('o');
const [tableData, setTableData] = useState([ ['','',''],['','',''],['','',''] ]);
}
실제 이벤트 발생하는 곳이 Td컴포넌트 인데, tictactoe 에서 state들을 td로 보내려면
두번이나 거쳐서 Td로 가는 문제점이발생
state 갯수를 줄일수 있는 useReducer
const [state, dispatch] = useReducer( reducer, initialState );
useReducer를 불러오고
const [state, dispatch] = useReducer( reducer, initialState );
//(1) state들
const initialState = {
winner: '',
turn :'o',
tabledate: [ ['','',''],['','',''],['','',''] ]
}
// const [winner, setWinner] = useState('');
// const [turn, setTurn] = useState('o');
// const [tableData, setTableData] = useState([ ['','',''],['','',''],['','',''] ]);
//(2) state들을 어떻게 바꿀지.
const reducer = (state, action) =>{
}
(1) initialState : 필요한 state담는다.
state 에서 initialState를만들었기 때문에, initialState에 정의해놓은 winner를 state.winner로 접근이가능
state = useReducer( reducer, initialState );
dispatch = useReducer( reducer, initialState );랑 같으니까?
(2) reducer : reducer함수에 state들을 어떻게 바꿀지 정의.
(3) dispatch ({ /*action*/ }) : action 실행
ex)만약 winner를 o로 바꾸려면?
dispatch ({ /*action*/ type:'SET_WINNER', winner:'o' })
타입이름과 이름을 적어서 액션객체를만들어준다.
이액션 객체를 dispatch로 실행하는것.
액션으로 이렇게 원하는 state를 적어줬다고 해서 자동으로 state가 바뀌지 않음
action을 해석해서 state를 바꿔주는게 reducer.
action이 dispatch(실행)될때마다, reducer함수가 실행되는것!
//state들을 어떻게 바꿀지.
const reducer = (state, action) =>{
switch( action.type ){
case 'SET_WINNER' :
return{
...state,
winner:action.winner
}
}
}
const onClickTable = useCallBack ( ()=>{
//table클릭시 winner를 o로 바꾼다
dispatch ({ /*action*/ type:'SET_WINNER', winner:'o' })
},[])
그런데 action은 여러개고, 그때마다 reducer함수가 실행됨.
그래서 reducer함수 에서 어떤action인지 알아내야 되서 action.type을 써서 구분.
state.winner = action.winner이런식으로 바꾸면안된다는점
import React , { useState , useReducer , useCallback } from 'react';
import Table from './Table';
const initialState = {
winner: '',
turn :'o',
tabledate: [ ['','',''],['','',''],['','',''] ]
}
//state들을 어떻게 바꿀지.
const reducer = (state, action) =>{
switch( action.type ){
case 'SET_WINNER' :
return{
...state,
winner:action.winner
}
}
}
const Tictactoe = () =>{
const [state, dispatch] = useReducer( reducer, initialState );
const onClickTable = useCallback ( ()=>{
//table클릭시 winner를 o로 바꾼다
dispatch ({ /*action*/ type:'SET_WINNER', winner:'o' })
},[]);
return (
<>
<Table onClickTableEvent={onClickTable} />
{state.winner && <p>{state.winner} 님의 승리</p> }
</>
)
}
export default Tictactoe;
자식에게 onClick으로 .. onClickTable함수를 넘겨줬고
import React from 'react';
import Tr from './Tr';
const Table = ( {onClickTableEvent} )=>{
return(
<>
<table onClick={onClickTableEvent}>
<tbody>
<Tr>{''}</Tr>
</tbody>
</table></>
)
}
export default Table;
onClickTableEvent으로넘겨줬으니까 onClickTableEvent으로받야아 한다 **(또르륵..)
그리고 action.type은 변수로 빼준다
대문자로써주는게 코딩컴벤션.
배열로 tr, td컴포넌트 만들기
Tictactoe에 있는 initialState 에 선언해 놓은 2차원 배열 값들( [ ['','',''],['','',''],['','',''] ] )을 이제
[] [] [] 이걸 tr컴포넌트, 안에있는3개 를 td컴포넌트 로 만든다.
(1)Tictactoe에서 Table에게
tableData를 props으로 넘겨줌.
<Table onClickTableEvent={onClickTable}
tableData={state.tableData} />
(2)table에서 tableData props를 받아서
요소가 3개인 배열을 만들고
Array(3)
{Array(tableData.length).fill() } <Tr />
map 반복문으로 [ [],[],[] ] [] 를 tr로 받아서
갯수만큼 자식 컴포넌트를 만든다
{ Array(tableData.length).fill().map( ( tr )=>( <Tr /> ) ) }
(3) table -> Tr에게 각 [] 하나씩 넘겨줌.
{ Array(tableData.length).fill().map( ( tr )=>( <Tr /> ) ) }
{ Array(tableData.length).fill().map( ( tr ,i )=>( <Tr trData={ tableData[i] } /> ) ) }
(4) Tr 에서 trData props를 받아서
td를 3개 만든다.
<tr><Td /></tr>
<tr>
{ Array(trData.length).fill().map(( td )=>( <Td /> ) )}
</tr>
셀 하나하나가 다 컴포넌트 !
//Tictactoe.jsx
import React , { useState , useReducer , useCallback } from 'react';
import Table from './Table';
const initialState = {
winner: '',
turn :'o',
tabledate: [ ['','',''],['','',''],['','',''] ]
}
const SET_WINNER = 'SET_WINNER';
//state들을 어떻게 바꿀지.
const reducer = (state, action) =>{
switch( action.type ){
case SET_WINNER :
return{
...state,
winner:action.winner
}
}
}
const Tictactoe = () =>{
const [state, dispatch] = useReducer( reducer, initialState );
const onClickTable = useCallback ( ()=>{
//table클릭시 winner를 o로 바꾼다
//dispatch ({ /*action*/ type: SET_WINNER, winner:'o' })
},[]);
return (
<>
<Table onClickTableEvent={onClickTable}
tableData={state.tabledate}
/>
{state.winner && <p>{state.winner} 님의 승리</p> }
</>
)
}
export default Tictactoe;
// Table.jsx
import React from 'react';
import Tr from './Tr';
const Table = ( {onClickTableEvent, tableData } )=>{
return(
<>
<table onClick={onClickTableEvent}>
<tbody>
{ Array(tableData.length).fill().map( ( tr ,i)=>( <Tr trData={ tableData[i] }/> ) ) }
</tbody>
</table></>
)
}
export default Table;
//Tr.jsx
import React from 'react';
import Td from './Td';
const Tr = ({trData}) =>{
return(
<tr>
{ Array(trData.length).fill().map(( td )=>( <Td /> ) )}
</tr>
)
}
export default Tr;
//Td.jsx
import React from 'react';
const Td = ()=>{
return(
<td></td>
)
}
export default Td;
'React > basic' 카테고리의 다른 글
13. (3) useReducer (0) | 2020.07.29 |
---|---|
13. (2) useReducer (0) | 2020.07.29 |
12. hooks / useEffect , useMemo (0) | 2020.07.28 |
12. componentDidUpdate , setInterval (0) | 2020.07.27 |
11 (2)hooks / useEffect (0) | 2020.07.26 |