카테고리 없음

thunk, saga ,Sequelize ,주요함수

kim help 2022. 5. 4. 15:30
60 thunk, saga ,Sequelize ,주요함수

thunk

액션 객체가 아닌 함수를 디스패치 할 수 있습니다.

코드 예시

```
const thunk = store => next => action =>
  typeof action === 'function'
    ? action(store.dispatch, store.getState)
    : next(action)
```

미들웨어를 사용하면 함수를 디스패치 할 수 있다고 했는데요, 함수를 디스패치 할 때에는,
해당 함수에서 dispatchgetState 를 파라미터로 받아와주어야 합니다.
이 함수를 만들어주는 함수를 우리는 thunk 라고 부릅니다.

사용 예시

const getComments = () => (dispatch, getState) => {
  // 이 안에서는 액션을 dispatch 할 수도 있고
  // getState를 사용하여 현재 상태도 조회 할 수 있습니다.
  const id = getState().post.activeId;

  // 요청이 시작했음을 알리는 액션
  dispatch({ type: 'GET_COMMENTS' });

  // 댓글을 조회하는 프로미스를 반환하는 getComments 가 있다고 가정해봅시다.
  api
    .getComments(id) // 요청을 하고
    .then(comments => dispatch({ type: 'GET_COMMENTS_SUCCESS', id, comments })) // 성공시
    .catch(e => dispatch({ type: 'GET_COMMENTS_ERROR', error: e })); // 실패시
};

async await 활용

const getComments = () => async (dispatch, getState) => {
  const id = getState().post.activeId;
  dispatch({ type: 'GET_COMMENTS' });
  try {
    const comments = await api.getComments(id);
    dispatch({ type:  'GET_COMMENTS_SUCCESS', id, comments });
  } catch (e) {
    dispatch({ type:  'GET_COMMENTS_ERROR', error: e });
  }
}

thunk 예제

const {createStore,compose,applyMiddleware} =require('redux')
const {rootReducer} = require('./reducers')

//thunk

//1. thunk 정의

const  thunk =({dispatch,getState})=>(next)=>(action)=>(

typeof  action === 'function'

? action(dispatch)

: next(action)

)

//2. 변수에 담기

const  middleware = [thunk]

  

//3. compose를 사용해 enhancer을 만들어준다.

const  enhancer = compose(applyMiddleware(...middleware)) //applyMiddleware 안에 함수가 들어감

  

//4. store에 rootReducer,enhancer를 담아준다.

const  store = createStore(rootReducer,enhancer)

  

console.log(store.getState());

  

store.dispatch({type:'asda'})

store.dispatch({type:'asda'})

store.dispatch({type:'asda'})

store.dispatch({type:'asda'})


const  aa = ()=>{

console.log('여기까지 가능');

const  bb = (dispatch)=>{

dispatch({type:'나는 로그인할거임'})

}

return  bb

}

store.dispatch(aa())

실행 후 모습

thunk compose

미들웨어란, 액션과 리듀서 사이에 존재합니다. 특정 액션을 가하고 리듀서가 처리하기 전에 작업을 처리합니다.

일반적으로 store를 생성하는 법

const store = createStore(reducer); 

applyMiddleware를 활용하여 미들웨어를 거쳐가도록 하는 store 생성법

const store = createStore(RootReducer, applyMiddleware(promiseMiddleware, ReduxThunk))

SAGA

saga는 제너레이터 함수의 yield에서 call effect가 발생할때 promise가 resolve될 때까지 기다리다가,
완료되면 제너레이터의 next()를 호출하여 다음으로 이동
한다.

dispatch 후에 함수를 추적해서 실행함

saga 기본 세팅

import saga from ‘redux-saga’

const {takeEvery,takeLatest, call, put} = require('redux-saga/effects')

saga 연습 gen.js

function*  gen3(){

let  a = yield

console.log(a);

let  b = yield

console.log(b);

yield  3

yield  4

return  5

}

  

function*  middle(){

console.log('접근');

while(true){

const  action = yield;

if (action.type === 'ingoo'){

console.log('qudtls');

}

}

}

const  a = middle()

  

const  b = gen3()

콘솔창에서 a.next(‘ingoo’)라고 치면 그에 해당하는 콘솔로그 값이 나온다.
b.next(값) 도 똑같다.

saga 예제

const {createStore,compose,applyMiddleware} =require('redux')

const {rootReducer} = require('./reducers')

const  reduxSaga = require('redux-saga')

const {takeEvery,takeLatest, call, put} = require('redux-saga/effects')

  

function  loginAPI(id,pw){

return  axios.post('url')

}

  

function*  change(action){

const {payload:{id,pw}}=action

console.log(id,pw);

try{

const  result = yield  call(loginAPI(),id,pw)

//성공

yield  put({type:'성공'})

}catch (e){

//실패

yield  put({type:'실패'})

}

}

  

// SAGA

  

// import saga from 'redux-saga'

//dispatch 후에 함수를 추적해서 실행함

  

function*  change(action){

console.log(action);

  

}

  

function*  rootSaga(){

//1. action 상태를 확인 하고싶다.

//take 액션값이 같을경우, 특정함수를 호출하는 그런아이

// 1번째 인자값은 , type내용 ,2번째 인자값은 ,호출할 함수명 함수가 하나일때

console.log('hello world');

yield  takeEvery('ingoo',change)

// yield takeLatest('ingoo',change)

}

  

const  sagaMiddleware = reduxSaga.default()

const  middleware = [sagaMiddleware]

  

const  enhancer = compose(applyMiddleware(...middleware)) //applyMiddleware 안에 함수가 들어감

const  store = createStore(rootReducer,enhancer)

  

sagaMiddleware.run(rootSaga)

  
  

store.dispatch({type:'ingoo'})

Sequelize DB에 연결

/*

ORM

sequelize = DBMS mysql,oracle,mssql,postgresql... 관리

  

mysql2

  

mysql.createPool('접속정보~')

  

nodejs 코드에서 > mysql 접속

SQL

webserver select 문을 작성해서 보냈다면

이것은 ORM find() = select * from 으로 보내준다.

  
  

mysql2 sequelize

*/

  

const {Sequelize, DataTypes}= require('sequelize')

  

//인자값이 4개임

//1. 데이터베이스명

//2. 데이터베이스 계정명 > mysql -u ssss

//3. 데이터베이스 패스워드

//4. Object 객체 넣음

//5. host 적어줌

//6. dialect:'mysql' 사용하는 db

const  sequelize = new  Sequelize('example','ingoo','ingoo',{

host:'localhost',

dialect:'mysql'

})

  

// sequelize.sync()

// .then(data=>{

// console.log('접속됨');

// }).catch(error =>{

// console.log('실패됨');

// })

  

async  function  init(){

try{

await  sequelize.sync()

console.log('접속');

comment()

//코드를 작성하면 sequelize 코드를 다 실행할 수 있음,

}catch(e){

console.log('실패');

}

}

  

init()

  

function  comment(){

//model 만들기

const  USER = sequelize.define('comment',{

//field 내용

subject:{

type:DataTypes.STRING(30),

allowNull:false,

},

content:{

type:DataTypes.STRING(50),

allowNull:false

}

},{

//옵션 정보

tableName:'ingoo',

timestamps:false

})

return  USER

}

  

const  insert = async ()=>{

const  USER = comment()

await  USER.create({subject:'adsf',content:'asdf'})

}
아직 노트북에 mysql이 설치되지 않아서 실패라고 뜬다.

yield

yield는 마치 return 처럼 동작하며 정해진 구간을 순서대로 실행하며 반드시 ‘function*’ 을 사용한 함수에서 사용합니다.

주요함수

delay

설정된 시간 이후에 resolve하는 Promise객체를 리턴한다.
예시: delay(1000)
→ 1초 기다리기

put

특정 액션을 dispatch하도록 한다.
예시: put({type: 'INCREMENT]})
→INCREAMENT action을 dispatch한다.

takeEvery

들어오는 모든 액션에 대해 특정 작업을 처리해 준다.
예시: takeEvery(INCREASE_ASYNC, increaseSaga)
→들어오는 모든 INCREASE_ASYNC액션에 대해 increaseSaga 함수 실행

takeLatest

기존에 진행 중이던 작업이 있다면 취소 처리하고 가장 마지막으로 실행된 작업만 수행한다.
예시: takeLatest(DECREASE_ASYNC, decreaseSaga)
→DECREASE_ASYNC액션에 대해서 기존에 진행 중이던 작업이 있다면 취소 처리하고 가장 마지막으로 실행된 작업에 대해서만 decreaseSaga함수를 실행한다.

call

함수의 첫 번째 파라미터는 함수, 나머지 파라미터는 해당 함수에 넣을 인수이다.
예시: call(delay, 1000)
→delay(1000)함수를 call함수를 사용해서 이렇게 쓸 수도 있다.

callput의 다른 점은 put은 스토어에 인자로 들어온 action을 dispatch하고, call인 경우에는 주어진 함수를 실행하게 되는 것이다.

all

all함수를 사용해서 제너레이터 함수를 배열의 형태로 인자로 넣어주면, 제너레이터 함수들이 병행적으로 동시에 실행되고, 전부 resolve될때까지 기다린다. Promise.all과 비슷하다고 보면된다.
예시: yield all([testSaga1(), testSaga2()])
→ testSaga1()과 testSaga2()가 동시에 실행되고, 모두 resolve될 때까지 기다린다.