TIL 2018-05-28
오늘 배운 것
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에 커스텀 쿼리를 작성한다.
…/queries/myquery1.gql
fragment MyType on MyType {
text
}
…/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이랑 연결되는 식이었는데, 바꾸려면 어떻게 해야 하나??
Comments