ryu110
@ryu110

Are you sure you want to delete the question?

Leaving a resolved question undeleted may help others!

apollo reactを使用して引数であるidを渡したい

Q&A

Closed

apollo reactを使用して引数であるidを渡したいです。詳細ページに移動したときにurlのところも......../idになっているので問題はないです。

やりたいこととしては、投稿リストがある、その一つ一つに詳細ボタンがついています。その詳細ボタンを押すとForm内容が見れるという感じです。

省略はしていますがここからidを渡して

 <div>
  <NavLink to={`/AllPostsShow/${id}`}>
    <Button onClick={() => detailPostButton(id)}>
       詳細
    </Button>
  </NavLink>
 </div>

これでSinglePostShowの中にidはわたっていました。

 const detailPostButton = (id:number) => SinglePostShow({id})

その中身は下記です。


import { useQuery, gql } from '@apollo/client'

const SINGLE_POST_DETAIL = gql`
  query singleDetail($id: Int) {
    singleDetail(id: $id) {
      id
      title
      content
    }
  }
`

export const SinglePostShow = ({id}:{id:number}) => {
  console.log(id,'id')

  const {
    data,
    loading,
    error
  } = useQuery(SINGLE_POST_DETAIL,{
    variables:{
      id
    },
  })

  if (loading) return <p>Loading...</p>
  if (error) return <p>Error...</p>

  const {id:singleId,title,content} = data


  return (
    <div key={singleId}>
      詳細フォーム
      <input>{title}</input>
      <input>{content}</input>
    </div>
  )
}

export default SinglePostShow

qraphqlで確認した時もidを引数に渡せば値が返ってきます。
なのでbackendは問題なさそうです。

何がおかしいのでしょうか?

0

4Answer

Comments

  1. @ryu110

    Questioner

    detail buttonを押したときにsingledetailの情報が出てこないです。
    backemdは問題なさそうです。frontのIDの受け渡し方かapolloの使い方が間違っているのかなと思います
// イベントの中でこの関数を呼んでいる
<Button onClick={() => detailPostButton(id)}>
詳細
</Button>

// この関数はSinglePostShowコンポーネントを関数として呼んでいる
const detailPostButton = (id:number) => SinglePostShow({id})

// これはコンポーネント
// コンポーネントなら  <SinglePostShow id={id}/>  という風に呼ぶべきでは?
// 最終的にうまく行ったとしても、コンポーネントをclickイベント内で作って表示できる気がしない...
export const SinglePostShow = ({id}:{id:number}) => {
  ...
}

多分やりたいことはこうなのでは?

const [detailId, setDetailId] = React.useState<number>(null)

...
...

<Button onClick={() => setDetailId(id)}>
詳細
</Button>

{Boolean(detailId) && (<SinglePostShow id={detailId}/>)}
...
...
0Like

Comments

  1. @ryu110

    Questioner

    できないですね。SinglePostShowの中にidを渡せなくなりました。
  2. > idを渡せなくなりました

    どういう結果から渡せないと判断してますか?
  3. @ryu110

    Questioner

    <NavLink to={`/AllPostsShow/${id}`}>
    <Button onClick={() => setDetailId(id)}>詳細</Button>
    </NavLink>

    のようにLinkの中に入れてしまうとidが渡されないですね。


    なのでButtonを外に出して、
    {Boolean(detailId) && <SinglePostShow id={detailId} />}は
    mapの外に置いてみました。

    今度はIdは渡せますが、http://localhost:3000/AllPostsShow/:idのページにいかずに、
    http://localhost:3000/AllPostsShowのところでただcomponentがでてきただけでした。

    やりたいこととしてはページを遷移させてsinglepostdetailPageにいき、そこでdata作成したdataを出したいです(apolloを使用して)
import { useQuery, gql, useMutation } from '@apollo/client'
import { Button, Col, Row } from 'antd'
import React from 'react'
import { NavLink } from 'react-router-dom'
import SinglePostShow from './SinglePostShow'

export const POST_DATA = gql`
  query allPosts {
    allPosts {
      id
      title
      content
    }
  }
`

const DELETE_POST = gql`
  mutation deletePost($id: Int) {
    deletePost(id: $id) {
      id
    }
  }
`

export const AllPostsShow = () => {
  const [detailId, setDetailId] = React.useState<any>(null)
  const [deletePost] = useMutation(DELETE_POST, {
    refetchQueries: ['allPosts'],
  })
  const {
    data: post_data,
    loading: post_loading,
    error: post_error,
  } = useQuery(POST_DATA)

  const deletePostButton = (id: number) => {
    deletePost({
      variables: {
        id,
      },
    })
    alert('削除しました')
  }

  if (post_loading) return <p>Loading...</p>
  if (post_error) return <p>Error...</p>
  return (
    <div className="postData">
      <Row gutter={[16, 16]}>
        {post_data.allPosts.length > 0 &&
          post_data.allPosts.map(
            ({
              id,
              title,
              content,
            }: {
              id: number
              title: string
              content: string
            }) => {
              return (
                <Col span={6} key={id}>
                  <div style={{ backgroundColor: 'beige' }}>
                    <p>タイトル:{title}</p>
                    <p>内容:{content}</p>
                    <div className="buttonPlace">
                      <Button onClick={() => deletePostButton(id)}>削除</Button>
                      <div>
                        <NavLink to={`/AllPostsShow/${id}`}>
                          <Button onClick={() => setDetailId(id)}>詳細</Button>
                          {Boolean(detailId) && (
                            <SinglePostShow id={detailId} />
                          )}
                        </NavLink>
                      </div>
                    </div>
                  </div>
                </Col>
              )
            },
          )}
      </Row>
    </div>
  )
}

0Like

Linkの中に入れてしまうとidが渡されない

そんな事はないと思いますけど。

<NavLink to={`/AllPostsShow/${id}`}>
  <Button onClick={() => {

    console.log("id:", id)

  }>詳細</Button>
</NavLink>

こうしておけばロード時にそれぞれのidがコンソールに表示されると思います。

更に言うとpost_data.allPosts.mapの中なのでconst [detailId, setDetailId] = React...は各詳細を個別に表示するという意味では使えない(最初の例だとmapの中だとは書かれてない...)。
たとえこれがちゃんと動いたとしても、どれか1つの詳細ボタンを押したら全部の詳細が一度に表示されると思います。

ページを遷移させてsinglepostdetailPageにいき、そこでdata作成したdataを出したい

<NavLink to={`/AllPostsShow/${id}`}>

これがクリックイベントでページ遷移を起こすなら、そもそも表示中のページはなくなってしまうので、<Button onClick={...} で何をやろうが表示されないはずでは?

ちょっとやっている事がよく分かりません。

  • export const AllPostsShow = () => {...} これが/AllPostsShowというサイトのパスで表示されるもの?
  • そうであるならどうやって/AllPostsShow/${id}のid部分をこのコンポーネントが受け取っている?
  • そもそもSinglePostShowというコンポーネントを表示させるだけなら、なぜページ遷移をする?

各ボタンクリックで個別に詳細表示なら、別コンポーネントを用意して、その中で状態を保持したほうが表示・非表示は楽かもしれません。
ページ遷移は必要なさそうなので取りました。

interface Props{
  id: number
}
const DetailButton: React.FC<Props> = ({id}) => {
  const [open, set] = React.setState(false)

  return (
    <>
      <Button onClick={() => set(prev => !prev)}>詳細</Button>
      {open && <SinglePostShow id={id} />}
    </>
  )
}

export const AllPostsShow = () => {

...
...

  <div className="buttonPlace">
    <Button onClick={() => deletePostButton(id)}>削除</Button>
    <div>
      <DetailButton id={id} />
    </div>
  </div>

...
...
}
0Like

Comments

  1. @ryu110

    Questioner

    ありがとうございます。
    NaveLinkでURLにIdを持たせてuseParamsとかでidとれるかなとも考えていました
  2. @ryu110

    Questioner

    とりあえず表示はできました

Your answer might help someone💌