LoginSignup
0
0

More than 1 year has passed since last update.

Amplifyの公式ワークショップをなぞったメモ

Posted at

Amplify SNS Workshopをやってみて気付いたことのメモ。説明は書いてくれてあるけど、それ以外でメモっておきたいこと。Reactの書き方についてが主なので慣れてる人にとっては何にもならない情報。

3.5 Post機能 Front-end

Sidebar, PostList ⊂ AllPosts, PostsBySpecifiedUser みたいな構造

Sidebar.js (左側) + PostList.js (右側) = AllPosts.js or PostsBySpecifiedUser (全体)

ただし、PostListは以下のようなpropsを持ち、postの取得自体はAllPosts or PostsBySpecifiedUserで行なっている。

const PostList = ({ isLoading, posts, getAdditionalPosts, listHeaderTitle, listHeaderTitleButton }) => {...}

App.jsではRouterでAllPostsかPostsBySpecifiedUserを指定されたパスによって表示

function App() {
  const classes = useStyles();
  return (
    <div className={classes.root} >
      <ThemeProvider theme={theme}>
        <CssBaseline />
        <HashRouter>
          <Switch>
            <Route exact path='/' component={AllPosts} />
            <Route exact path='/global-timeline' component={AllPosts} />
            <Route exact path='/:userId' component={PostsBySpecifiedUser}/>
            <Redirect path="*" to="/" />
          </Switch>
        </HashRouter>
      </ThemeProvider>
    </div>
  );
}

userIdPostsBySpecifiedUser内部でuseParams()で取得可能

Drawerは左側のメニューみたいな部分

Sidebar.jsのメニュー部分はmaterial-uiのDrawerコンポーネント

@authのownerFieldがあるおかげで、createpostするときにcognito identity(ユーザーID)が自動で挿入されてくれる

schema.graphqlのディレクティブの話。クエリで特にユーザーIDを指定していないのにDynamoDBにはちゃんと入っていたのはこのせいみたい。

useEffect()の最後のreturnはクリーンアップと言って、コンポーネントが画面から消える時に実行されるReactの機能っぽい

5.3 Timeline機能 Back-end

Follow/Timelineの時にLambdaリゾルバ によりPostテーブルへ作成することにしてる。多分処理が複雑になってフロントエンド でいじるよりかはこっちで共通処理作ったほうが楽だからだろう

@connectionでのリレーション

schema.graphqlのディレクティブの話。Timelineオブジェクトのこの部分↓で、指定したpostIdをidにもつpostを持ってこられる。クエリの時にはpostIdを指定するだけでいい。

    postId: ID!
    post: Post @connection(fields: ["postId"])

Lambdaリゾルバを呼び出すMutationを追加

引数がcontent, 返り値がPost型

type Mutation
{
  createPostAndTimeline(
    content: String!
  ): Post
@function(name: "...")

5.4 Timeline機能 @function

Lambda 関数内での処理について。

  • export default = object;している場合にはrequire('object').defaultにしないといけないらしい。
  • LambdaにAppSyncから渡されるeventデータの構造はこのdocument
  • createPostするたびに全てのfollowerのタイムラインに順次投下。
    • Promise.allで全部の結果が返ってくるまで待つ。
    • createTimelineForAUser()は投稿された単一のpostをあるfolloweeのタイムラインテーブルに投下する。
const results = await Promise.all(followers.map((follower) => {createTimelineForAUser({follower: follower, post: post})}));
  • Lambdaで使うgqlクエリは自動生成されたものをコピペした。もっといい方法はないんだろうか(なさそう

5.5 Timeline機能 Front-end

Timeline.jsではuseEffect()を二つ使っており、どちらが先に発動するかは読めないよう

if(!currentUser) return; を入れ忘れてエラーが出ていた。
subscriptionを作る方のuseEffect(2個目の方)が実行された段階でcurrentUsernullだった。そのあとcurrentUserの状態が変わった時にもう一度処理が走り、計2回処理が走るようだ。

  useEffect(() => {
    const init = async () => {
      const currentUser = await Auth.currentAuthenticatedUser();
      setCurrentUser(currentUser);
      getPosts(INITIAL_QUERY, currentUser);
    }
    init();
  }, []);

  useEffect(()=> {
    if(!currentUser) return;
    const subscription = ...
  }, [currentUser])

Sidebar.jscreatePostAndTimelineの引数

以下のような形式で間違えてinputを入れていたら、なぜかlambdaが実行すらされずトラシューが超大変だった(正しくは{content: value}のみ)}。

const res = await API.graphql(graphqlOperation(createPostAndTimeline, {input:{content: value}}))

手動でonにしたappsyncのログ(成功時(上記のinputを無くした時))

 GraphQL Query: mutation CreatePostAndTimeline($content: String!) {
  createPostAndTimeline(content: $content) {
    type
    id
    content
    owner
    timestamp
  }
}
, Operation: null, Variables: {
    "content": "test11"
}

inputがあったときのログ(lambdaが実行されず失敗)。variablesが違うだけ。

Query: mutation CreatePostAndTimeline($content: String!) {
  createPostAndTimeline(content: $content) {
    type
    id
    content
    owner
    timestamp
  }
}
, Operation: null, Variables: {
    "input": {
        "content": "test11"
    }
}
0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0