62753


住所などの入力ホームにて、郵便番号を入力するとリアルタイムで関連する住所を返してくれるPostcodeJP
APIを利用しているのですが、stateが変更されてもレンダーされず、前の値のままになる。  
例 郵便番号の欄に 8701121 を入力すると
本当の住所は大分県・大分市・鴛野ですが、大分県・大分市しか表示されず、入力を87011210などに変えると、鴛野まで表示される。  
問題のサイト  
<https://e-commerce-with-gatsby.netlify.com/>

state自体は変更されているのですが、レンダーされていない（UIに反映されていない。）

以下がコードです。

[code]

    import React, { useEffect, useState } from "react"
    import { useSelector } from "react-redux"
    import { css } from "@emotion/core"
    import styled from "@emotion/styled"
    import { CardElement, injectStripe } from "react-stripe-elements"
    import uuidv1 from "uuid/v1"
    import media from "@styles/media"
    
    const CheckoutForm = ({ stripe, toggleOverlay }) => {
      const [address, setAddress] = useState("")
      const [address2, setAddress2] = useState("")
      const [city, setCity] = useState("")
      const [email, setEmail] = useState("")
      const [name, setName] = useState("")
      const [prefecture, setPrefecture] = useState("")
      const [postalcode, setPostalcode] = useState("")
      const [status, setStatus] = useState("")
    
    
      const handlePostcode = async event => {
        setPostalcode(event.target.value)
    
        try {
          const headers = {
            apikey: process.env.GATSBY_POSTCODE_API_KEY,
          }
    
          await fetch(
            `https://apis.postcode-jp.com/api/v3/postcodes?postcode=${postalcode}&startWith=true&normalize=true&general=true&office=true`,
            {
              method: "GET",
              headers,
            }
          ).then(response => {
            if (response.status === 200) {
              response.text().then(text => {
                const addressData = JSON.parse(text).data[0]
                if (JSON.parse(text).size > 0) {
    
                  #各stateを変更
                  setCity(addressData.city)
                  setPrefecture(addressData.pref)
                  setAddress(addressData.town)
                } else {
                  setCity("")
                  setPrefecture("")
                  setAddress("")
                }
              })
            } else {
              response.text().then(text => console.log(text))
              throw new Error("Network response was not ok.")
            }
          })
        } catch (error) {
          setStatus("error")
          console.log(error)
        }
      }
    
      const handleSubmit = async event => {
       #stripeに関するfunction
      }
    
      useEffect(() => {
        #省略
      }, [postalcode, city, address, prefecture])
    
      return (
        <Container>
          <Form>
            <FieldHeading>お届け先住所</FieldHeading>
            <Field>
              <Row>
                <Label htmlFor="postalcode">郵便番号</Label>
                <Input
                  id="postalcode"
                  type="text"
                  placeholder="112-3200"
                  onChange={handlePostcode}
                />
              </Row>
              <Row>
                <Label htmlFor="prefecture">都道府県</Label>
                <Input
                  id="prefecture"
                  type="text"
                  placeholder="滋賀県"
                  value={prefecture}
                  onChange={event => setPrefecture(event.target.value)}
                />
              </Row>
              <Row>
                <Label htmlFor="city">市区町村</Label>
                <Input
                  id="city"
                  type="text"
                  placeholder="南城市"
                  value={city}
                  onChange={event => setCity(event.target.value)}
                />
              </Row>
              <Row>
                <Label htmlFor="sddress">住所</Label>
                <Input
                  id="address"
                  type="text"
                  placeholder="津波古112-2"
                  value={address}
                  onChange={event => setAddress(event.target.value)}
                />
              </Row>
              <Row>
                <Label htmlFor="address2">
                  建物名・
                  <br />
                  部屋番号
                </Label>
                <Input
                  id="address2"
                  type="text"
                  placeholder="レオパレスGatsby 202"
                  onChange={event => setAddress2(event.target.value)}
                />
              </Row>
            </Field>
    
            <FieldHeading>お支払い情報</FieldHeading>
            <Field>
              <Row>
                <CardElement {...createOptions()} id="card" className="empty" />
              </Row>
            </Field>
    
            <CheckoutButton
              type="submit"
              disabled={status === "submitting"}
              onClick={handleSubmit}
            >
              {status === "submitting" ? "送信中" : "注文する"}
            </CheckoutButton>
          </Form>
        </Container>
      )
    }
    
    export default injectStripe(CheckoutForm)
    
[/code]


CC BY-SA 4.0
2020-02-02T01:31:36.380
62706
2020-02-04T00:21:40.940
37676
question
reactjs
React Hooks で State を変更しても再レンダーされない。


APIのクエリパラメータ "postcode" に変数 `postalcode` を使っているためだと推測します。 `event.target.value`
の値を渡すことで解決すると思います。

[code]

    await fetch(
      `https://apis.postcode-jp.com/api/v3/postcodes?postcode=${event.target.value}&startWith=true&normalize=true&general=true&office=true`,
      ...
    
[/code]

参考: <https://ja.reactjs.org/docs/hooks-faq.html#why-am-i-seeing-stale-props-
or-state-inside-my-function>

DevTools などを使って確認できますが、リクエストする URL
が期待通りになっていないはずです。ですので、質問にあるようにレンダリングが行われていないわけではありません。


CC BY-SA 4.0
2020-02-04T00:21:40.940
62753
2020-02-04T00:21:40.940
32959
62706
answer