sugya
@sugya

Are you sure you want to delete the question?

Leaving a resolved question undeleted may help others!

useStateで値を保持出来ない理由を知りたい

Q&A

Closed

※友人への質問として記述している為、公に書いている訳ではございません。

解決したいこと

新規レビュー作成機能実装中で、useStateに上手く値を保持出来ない。

review_json.
{
  review: {
    user_id: 1,
    company_id: companyInformation.companies.id,
    review_category_id: reviewCategoryId,
    review_content: content,
  },
}

具体的には、
新規レビュー作成(POST_api)を、「投稿する」ボタンをクリックと同時に送っているが、

発生している問題・エラー

Response.
{"status":500,"errors":["Company must exist","Review category must exist","Enrollment must exist"]}

デベロッパーツールのNetworkでは、下記のような500エラーが発生する。
※一番右のEnrollmentに関しては、実装してないので予想通りだが、
CompanyとReview_categoryに関しては、実装していたつもりなので、予想外。

さらに、apiを叩いて、成功している場合はsuccesが呼ばれ、下記のような成功してるっぽい画面も出ている。

console.
{data: {…}, status: 200, statusText: "OK", headers: {…}, config: {…}, …}
config:
Content-Type: "application/json"
adapter: ƒ xhrAdapter(config)
data: "{"review":{"user_id":1,"review_content":"すぎゃの大冒険スペシャル"}}"
headers: {Accept: "application/json, text/plain, */*", Content-Type: "application/json;charset=utf-8"}
maxBodyLength: -1
maxContentLength: -1
method: "post"
timeout: 0
transformRequest: [ƒ]
transformResponse: [ƒ]
url: "http://localhost:3001/api/v1/companies/undefined/review_categories/undefined/reviews"
validateStatus: ƒ validateStatus(status)
xsrfCookieName: "XSRF-TOKEN"
xsrfHeaderName: "X-XSRF-TOKEN"
__proto__: Object
data:
errors: (3) ["Company must exist", "Review category must exist", "Enrollment must exist"]
status: 500
__proto__: Object
headers: {cache-control: "max-age=0, private, must-revalidate", content-type: "application/json; charset=utf-8"}
request: XMLHttpRequest {readyState: 4, timeout: 0, withCredentials: false, upload: XMLHttpRequestUpload, onreadystatechange: ƒ, …}
status: 200
statusText: "OK"
__proto__: Object

該当するソースコード

ReviewsNew.jsx
import React, { useEffect, useState } from 'react'
import axios from 'axios'
import { reviewsNew } from '../../urls/index'
import { SearchCompanies } from '../companies/SearchCompanies'

export const ReviewsNew = () => {
  const [searchKeyWord, setSearchKeyWord] = useState('')
  // 検索ワードを保持する
  const handleChange = (e) => {
    setSearchKeyWord(e.target.value)
  }
  // 検索ワードで企業を探す
  const companyInformation = SearchCompanies(searchKeyWord)

  // レビューコンテンツ
  const [content, setContent] = useState('')
  const [content2, setContent2] = useState('')
  const [reviewCategoryId, setReviewCategoryID] = useState()

  const handleSubmit = () => {
    const body = {
      review: {
        user_id: 1,
        company_id: companyInformation.companies.id,
        review_category_id: reviewCategoryId,
        review_content: content,
      },
    }
    console.log(companyInformation, reviewCategoryId)
    const headers = { 'Content-Type': 'application/json' }
    axios
      .post(
        reviewsNew(companyInformation.companies.id, reviewCategoryId),
        body,
        headers
      )
      .then((response) => {
        console.log('success', response)
        alert('レポート投稿が成功しました')
      })
      .catch((error) => {
        console.log('failed', error)
        alert('投稿に失敗しました')
      })
  }

  return (
    <>
      <input type="text" placeholder="医院で検索する" onChange={handleChange} />
      <h4>組織体制 / 企業文化</h4>
      <form>
        <textarea
          name="companyCulture"
          value={content}
          onChange={(event) => setContent(event.target.value)}
        />
        <button
          onClick={() => setReviewCategoryID(1)}
          onClick={handleSubmit}
          type="button"
        >
          この内容で投稿する
        </button>
      </form>
      <h4>入職した理由</h4>
      <form>
        <textarea
          name="JoinReason"
          value={content2}
          onChange={(event) => setContent2(event.target.value)}
        />

        <button onClick={handleSubmit} type="button">
          レポートを投稿する
        </button>
      </form>
    </>
  )
}
urls/index.js
const DEFAULT_API_LOCALHOST = 'http://localhost:3001/api/v1'

// ユーザー
export const usersNew = `${DEFAULT_API_LOCALHOST}/users`
export const usersLogin = `${DEFAULT_API_LOCALHOST}/login`
export const usersCheckLogin = `${DEFAULT_API_LOCALHOST}/logged_in`
export const usersShow = (id) => `${DEFAULT_API_LOCALHOST}/users/${id}`
export const usersEdit = (id) => `${DEFAULT_API_LOCALHOST}/users/${id}`

// 企業
export const companiesNew = `${DEFAULT_API_LOCALHOST}/companies`
export const companiesShow = (companyId) =>
  `${DEFAULT_API_LOCALHOST}/companies/${companyId}`
export const companiesIndex = `${DEFAULT_API_LOCALHOST}/companies`
// 企業検索
export const search = (keyword) =>
  `${DEFAULT_API_LOCALHOST}/companies/search?search=${keyword}`

// レビュー
export const reviewsNew = (companyId, reviewCategoryId) =>
  `${DEFAULT_API_LOCALHOST}/companies/${companyId}/review_categories/${reviewCategoryId}/reviews`
export const reviewsShow = (companyId, reviewCategoryId, reviewId) =>
  `${DEFAULT_API_LOCALHOST}/companies/${companyId}/review_categories/${reviewCategoryId}/reviews/${reviewId}`
export const reviewsIndex = (companyId, reviewCategoryId) =>
  `${DEFAULT_API_LOCALHOST}/companies/${companyId}/review_categories/${reviewCategoryId}/reviews`

// レビューカテゴリー
export const reviewCategoriesIndex = (companyId) =>
  `${DEFAULT_API_LOCALHOST}/companies/${companyId}/review_categories`
export const reviewCategoriesShow = (companyId, reviewCategoryId) =>
  `${DEFAULT_API_LOCALHOST}/companies/${companyId}/review_categories/${reviewCategoryId}`

// 在籍情報
export const enrollmentsNew = `${DEFAULT_API_LOCALHOST}/enrollments`
SearchCompanies.js
import React, { useState, useEffect } from 'react'
import axios from 'axios'

const initialState = {
  companies: [
    {
      id: null,
      name: '',
    },
  ],
}
export const SearchCompanies = (keyword) => {
  const [companyList, setCompanyList] = useState(initialState)

  const fetchCompany = (keyword) =>
    axios
      .get(`http://localhost:3001/api/v1/companies/search?search=${keyword}`)
      .then((res) => {
        return res.data
      })
      .catch((error) => {
        console.log(error)
        return { companies: [] }
      })

  useEffect(() => {
    fetchCompany(keyword).then(
      (data) => setCompanyList(data),
      console.log(companyList)
    )
  }, [keyword])

  return companyList
}

自分で試したこと

デバッグしていった結果、ReviewsNew.jsxにおいて、
reviewCategoryIdreviewInformationにstateを保持出来ていない事が分かった。
※console.logで2つとも表示させてようとしたが、undefindとなっていた。

イベントハンドラで発火させる場所が違っているかと思い、色々とstateを更新する箇所を変えてみたが、
変わらず更新出来なかった。

0

1Answer

Comments

  1. @sugya

    Questioner

    こんなご質問に回答頂いて有り難うございます!!
    解決致しました!!

Your answer might help someone💌