質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
87.20%
Laravel

LaravelとはTaylor Otwellによって開発された、オープンソースなPHPフレームワークです。Laravelはシンプルで表現的なシンタックスを持ち合わせており、ウェブアプリケーション開発の手助けをしてくれます。

React.js

Reactは、アプリケーションのインターフェースを構築するためのオープンソースJavaScriptライブラリです。

解決済

ReactでsetStateした後、再レンダリングが発生しない

YKita
YKita

総合スコア2

Laravel

LaravelとはTaylor Otwellによって開発された、オープンソースなPHPフレームワークです。Laravelはシンプルで表現的なシンタックスを持ち合わせており、ウェブアプリケーション開発の手助けをしてくれます。

React.js

Reactは、アプリケーションのインターフェースを構築するためのオープンソースJavaScriptライブラリです。

1回答

0評価

0クリップ

1231閲覧

投稿2021/10/05 10:35

前提・実現したいこと

Laravel + React(16.14.0)を使用しています。
axiosによるデータ取得後、リストとして表示する実装中に以下のエラーメッセージが発生しました。

発生している問題・エラーメッセージ

axiosで取得したデータをsetStateでstate更新した後、(おそらく)再レンダリングが起きていない。 その結果、画面にデータが表示されない。

該当のソースコード

親コンポーネント

react

import React, { useState, useEffect } from 'react'; import axios from 'axios'; import ReactDOM from 'react-dom'; import { Button, Container } from '@material-ui/core'; import AccountList from '../components/AccountList'; import CreateAccountForm from '../components/CreateAccountForm'; import Loading from './Loading' const Dashboard = () => { const [officialAccounts, setOfficialAccounts] = useState([]); const [loading, setLoading] = useState(true); useEffect(() => { getOfficialAccountsData(); }, []) const getOfficialAccountsData = () => { axios .get('/api/official_accounts') .then(response => { var newOfficialAccounts = [...response.data]; setOfficialAccounts(newOfficialAccounts); console.log(response.data); setLoading(false); }) .catch(() => { console.log('通信に失敗しました'); }); } if (loading) { return ( <Loading /> ); } return ( <Container> <div className="card"> <div className="card-header">公式アカウント管理</div> <div className="card-body"> <CreateAccountForm officialAccounts={officialAccounts} setOfficialAccounts={setOfficialAccounts} /> <AccountList officialAccounts={officialAccounts} /> </div> <Button color="secondary" variant="outlined">Logout</Button> </div> </Container> ); } export default Dashboard;

子コンポーネント

import React from 'react'; import ReactDOM from 'react-dom'; import List from '@material-ui/core/List'; import ListItem from '@material-ui/core/ListItem'; import ListItemSecondaryAction from '@material-ui/core/ListItemSecondaryAction'; import ListItemText from '@material-ui/core/ListItemText'; import IconButton from '@material-ui/core/IconButton'; import SettingsIcon from '@material-ui/icons/Settings'; import Paper from '@material-ui/core/Paper'; import green from '@material-ui/core/colors/green'; import { makeStyles, createStyles } from '@material-ui/core/styles'; import { useHistory } from 'react-router-dom'; const useStyles = makeStyles((theme) => createStyles({ })); function AccountList(props) { const classes = useStyles(); const { officialAccounts } = props; const history = useHistory(); return ( <List> {officialAccounts.map((officialAccount, index) => { <ListItem button key={index} onClick={() => history.push('user_list/' + officialAccount.id)} > <ListItemText primary={officialAccount.name} secondary={officialAccount.permission_name} /> <ListItemSecondaryAction> <IconButton disabled={!officialAccount.pivot.permission_id} type="submit" onClick={() => history.push('official_account_manage/' + officialAccount.id)} > <SettingsIcon /> </IconButton> </ListItemSecondaryAction> </ListItem> })} </List> ); } export default AccountList;

試したこと

ちなみに、現状の理解は、
①初回レンダリング時にuseEffectが実行され、stateが空配列から変更される
②stateの変更に伴い、子コンポーネントに渡すpropsの値が変化するため、子コンポーネントで再レンダリングがおこる
③officialAccountsの情報がlistコンポーネントに表示される
というプロセスなのですが、この理解で合っていますでしょうか?

ちなみに、検証ツールでみたところ、Listと対応するul はありました。中身のlistitemにあたるliがありません。
つまり、officialAccountsが空の状態のままであり、関数コンポーネントが再呼び出しされていないということになると思います。

補足情報(FW/ツールのバージョンなど)

良い質問の評価を上げる

以下のような質問は評価を上げましょう

  • 質問内容が明確
  • 自分も答えを知りたい
  • 質問者以外のユーザにも役立つ

評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

気になる質問をクリップする

クリップした質問は、後からいつでもマイページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

  • プログラミングに関係のない質問
  • やってほしいことだけを記載した丸投げの質問
  • 問題・課題が含まれていない質問
  • 意図的に内容が抹消された質問
  • 過去に投稿した質問と同じ内容の質問
  • 広告と受け取られるような投稿

評価を下げると、トップページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

hoshi-takanori

2021/10/05 11:10

console.log(response.data); で何が表示されてますか?
YKita

2021/10/05 11:21

{ access_token: "hogehoge" channel_id: "hogehoge" channel_secret: "hogehoge" created_at: "2021-09-23 00:09:14" id: 6 name: "hogehoge" permission_name: "管理者" pivot: { official_account_id: 6 official_account_permission: {id: 1, name: '管理者', created_at: null, updated_at: null} permission_id: 1 user_id: 1} [[Prototype]]: Object updated_at: "2021-09-23 00:09:14" webhook_url: "" } が要素の配列が表示されています。(access_tokenなどの中身は個人情報のため変更しています)
maisumakun

2021/10/05 11:46 編集

> つまり、officialAccountsが空の状態のままであり、関数コンポーネントが再呼び出しされていないということになると思います。 こちらの仮説を裏付ける検証は行ってみましたか?
YKita

2021/10/05 11:54

maisumakunさん 1. officialAccountsが空の状態のままであるかどうか useEffectにおいて、第二引数に[loading]を指定して関数コンポーネントを再呼び出ししました。その際、2回目のconsole.log(officialAccounts)には、上記response.dataと同じデータが入っていました。そのため、state更新自体は問題なくできていると考えています。 一方、useEffectの第二引数を空配列にした状態で, console.log(response.data); console.log(officialAccounts); を行うと、officialAccountsでは初期値である空配列が表示されています。 2. 関数コンポーネントが再呼び出しされていない に関して これは根拠のない予想です。setOfficialAccountによるstate変更が起きると、関数の再呼び出しがされて再描画がおこると考えています。そのため、再呼び出しが起きていないがために、再描画がされていないのではないかと考えました。

まだ回答がついていません

会員登録して回答してみよう

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
87.20%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問

同じタグがついた質問を見る

Laravel

LaravelとはTaylor Otwellによって開発された、オープンソースなPHPフレームワークです。Laravelはシンプルで表現的なシンタックスを持ち合わせており、ウェブアプリケーション開発の手助けをしてくれます。

React.js

Reactは、アプリケーションのインターフェースを構築するためのオープンソースJavaScriptライブラリです。