2 minute read

오늘 배운 것


ReactQL의 redux 및 graphql 구조 약간 파악.

커스텀 redux 액션을 추가하는데 성공했고, 커스텀 graphql 쿼리를 추가하는데 좀 애먹었지만 성공했다.

1. custom redux updater(reducer)

먼저, reactql에서는 app.js에서 리듀서를 추가한다.

import { counterReducer } from 'reducers';
.
.
.
config.addReducer('counter', counterReducer, { count: 0 });

config.addReducer는 key, reducer, initialState를 인자로 받으며, 인자로 전해진 initialState는 알아서 immutable이 된다고 한다. 여기서 counterReducer는 액션 'INCREMENT_COUNTER' 하나만 가지고 있는데, 이 액션은 카운터를 1씩 증가한다.

나는 여기에 카운터를 두 배로 늘리는 리듀서를 추가하려 했는데 잘 되지 않았다. 먼저 reducers/counter코드를 복사해서 이름 바꾸고 두 배로 늘리게 했더니, redux devtools에서 액션이 발생하지만 상태가 바뀌지 않았다.

그래서 원래 reducer에 곱하기 액션만 추가하는 식으로 했더니 잘 되었다.

아래와 같이 액션 MULTIPLY_COUNTER를 추가했다. reactql에서는


// Sample reducer, showing how you can 'listen' to the `INCREMENT_COUNTER`
// action, and update the counter state

// Note: There's no need to specify default state, because the kit's Redux
// init code wraps `undefined` state values in a `defaultReducer()` function,
// that captures Redux sentinel vals and responds back with a black object --
// so in our reducer functions, we can safely assume we're working with 'real'
// immutable state

export default function reducer(state, action) {
  if (action.type === 'INCREMENT_COUNTER') {
    // Where did `state.merge()` come from?  Our plain state object is automatically
    // wrapped in a call to `seamless-immutable` in our reducer init code,
    // so we can use its functions to return a guaranteed immutable version
    return state.merge({
      count: state.count + 1,
    });
  }

  if (action.type === 'MULTIPLY_COUNTER') {
    // Where did `state.merge()` come from?  Our plain state object is automatically
    // wrapped in a call to `seamless-immutable` in our reducer init code,
    // so we can use its functions to return a guaranteed immutable version
    return state.merge({
      count: state.count * 2,
    });
  }
  return state;
}

2. ReactQL에서 GraphQL 사용하기

먼저 루트 쿼리에 새로운 쿼리 타입 필드를 추가한다.


const Query = new GraphQLObjectType({
  name: 'Query',
  description: 'Root query object',
  fields() {
    return {
      message: {
        type: Message,
        resolve() {
          return getMessage();
        },
      },
      my1: {
        type: MyType,
        resolve() {
          return getMessage2();
        },
      },
    };
  },
});

// 아래는 구현
async function getMessage2() {
  return {
    text: `Hellodsdsdsds from the GraphQL server @ ${new Date()}`,
  };
} 

그리고 커스텀 쿼리 타입을 작성한다.


const MyType = new GraphQLObjectType({
  name: 'MyType',
  description: 'GraphQL MyType',
  fields() {
    return {
      text: {
        type: GraphQLString,
        resolve(msg) {
          return msg.text;
        },
      },
    };
  },
});

graphql/queries에 커스텀 쿼리를 작성한다.

:file_folder: …/queries/myquery1.gql

fragment MyType on MyType {
  text
}

:file_folder: …/queries/all_myquery.gql

#import "./myquery1.gql"

query myquery11{
  my1{
    ...MyType
  }
}

그리고 아래는 이 쿼리를 이용하는 리액트 컴포넌트이다.

import React, { Component } from 'react'
import PropTypes from 'prop-types';
import { graphql } from 'react-apollo'

import allMyquery from 'src/graphql/queries/all_myquery.gql';

@graphql(allMyquery)
export default class MyGraphQL1 extends Component {
  static propTypes = {
    data: PropTypes.shape({
      my1: PropTypes.shape({
        text: PropTypes.string,
      }),
    }),
  }

  static defaultProps = {
    data: {
      my1: {
        text: null,
      },
    },
  }

  render() {
    const { data } = this.props;
    const myquery1 = data.my1 && data.my1.text;
    const isLoading = data.loading ? 'yes' : 'nope';
    return (
      <div>loading : {isLoading}
        <br/>
        {myquery1}
        <br/>
        dslsldlsdsl sdldslsl</div>
    )
  }
}

myquery1.gql에서 루트의 myquery11은 리액트에서 불러오면서 allMyquery로 불러와졌고, 실제 this.props.data에 들어오는 정보의 이름은 my1임에 유의해야 한다.

3. add prisma binding to graphql

이 부분이 좀 문제일 것 같다. 현재 graphql 서버가 reactql에 있긴 한데 서버로서 prisma를 쓰려면 어떻게 설정을 해야 하는지 모르겠다. reactql에서는 그냥 config.enablegraphqlserver 호출하면 8081의 graphql이랑 연결되는 식이었는데, 바꾸려면 어떻게 해야 하나??

dep

ref


Comments