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

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

新規登録して質問してみよう
ただいま回答率
85.48%
React.js

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

Q&A

解決済

1回答

338閲覧

React HooksのContextの使い方

caren

総合スコア25

React.js

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

0グッド

0クリップ

投稿2022/09/22 05:32

前提

React(JavaScript)でログインページのあるwebアプリを作成しようとしています。

Home.jsxはLoginFormというコンポーネントを表示するコンポーネントです。
LoginForm.jsxはログインフォームのあるコンポーネントであり、submitボタンを押すとサーバー側にフォーム情報をPOSTし、DBにアクセスして、ログインしたユーザーのユーザー名を取得するコンポーネントです。(サーバー側の処理は問題ないことを確認済みです) 
しかし、ログインしているユーザー名は他のコンポーネントでも利用したいと思ったので、ログインしているユーザー名をContextで管理しようと思いました。
そこでUserNameProvider.jsxというContext用のコンポーネントを用意しました。

実現したいこと

ここに実現したいことを箇条書きで書いてください。

  • LoginForm.jsxで取得したユーザー名をHome.jsxで表示させたい

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

TypeError: "setUserName" is read-only at readOnlyError.js:2:9 at LoginForm.jsx:29:9

該当のソースコード

Home.jsx

1import {GAccordion} from "../components/GAccordion"; 2import React, { useState,useContext } from 'react'; 3import {LoginForm} from "../components/useForm/LoginForm"; 4import {UserNameContext} from "../components/providers/userNameProvider"; 5 6export const Home = () => { 7 8 const {userName,setuserName}=useContext(UserNameContext); 9 console.log(userName); 10 // const [pageName, changePageName] = useState('home'); 11 return ( 12 <> 13 <h1>Top Page :pageName :{userName}</h1> 14 <GAccordion /> 15 <LoginForm /> 16 </> 17 ); 18 19};

LoginForm.jsx

1 2import { useForm } from 'react-hook-form'; 3import React, { useContext,useEffect } from 'react'; 4import { Button, Input, Form } from 'semantic-ui-react'; 5import { UserNameContext } from '../providers/userNameProvider'; 6 7export const LoginForm = () => { 8 const { userName, setUserName } = useContext(UserNameContext); //context内のuserNameを取得 9 const { register, handleSubmit } = useForm(); 10 11const onSubmit = (data) => { 12 console.log(data); 13 const submitForm = document.querySelector('.login-form'); 14 const submitData = new FormData(submitForm); 15 fetch('http://localhost/MyWeb0711/getuserinfo.php', { 16 method: 'POST', 17 body: submitData 18 }) 19 .then((response) => { 20 if (!response.ok) { 21 throw new Error(`${response.status} ${response.statusText}`); 22 } 23 return response.text(); 24 }) 25 .then((data) => { 26 console.log('** fetch: then(data)'); 27 console.log(data); 28 setUserName =(data)=>data; //ここでエラーが出る 29 }) 30 .catch((reason) => { 31 console.log('** fetch: catch'); 32 console.log(reason); 33 }); 34 } 35 36 37 return ( 38 /* handleSubmitはラップした関数にformのdataをオブジェクト形式で渡してくれる 39 onSubmitの引数にデータがあるのはそのため。 */ 40 <form className="login-form" onSubmit={handleSubmit(onSubmit)}> 41 <input fluid label='User ID' placeholder='User ID' {...register('userid')} /> 42 <input fluid label='Password' placeholder='Password' {...register('password')} type="password" /> 43 <Button type="submit">log in</Button> 44 </form> 45 ); 46}; 47

UserNameProvider.jsx

1import { createContext,useState } from "react"; 2 3export const UserNameContext =createContext({}); //contextを作成 4 5export const UserNameProvider = props => { 6 const {children} =props; //propsとしてchildrenを受け取る 7 8 const [userName,setuserName]=useState("context成功"); //userNameをstateとして管理、そのstateの値と更新関数をcontextのvalueに設定する(どこからでもuserNameの参照と更新が可能) 9 10 // providerコンポーネントはvalueというpropsを設定でき、ここにグローバルに管理する値を渡していく 11 return ( 12 <UserNameContext.Provider value={{userName,setuserName}}> 13 {children} 14 </UserNameContext.Provider> 15 ); 16}; 17

試したこと

調べてみましたが解決方法がわかりません。

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

ここにより詳細な情報を記載してください。

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

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

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

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答1

0

ベストアンサー

javascript

1setUserName =(data)=>data; //ここでエラーが出る

エラーメッセージのとおり、この書き方ではsetUserNameの呼び出しではなく、setUserNameへの代入になってしまっています。

投稿2022/09/22 05:37

maisumakun

総合スコア145183

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

caren

2022/09/22 05:43

setUserNameで、userNameの値を書き換えたいときはどのように記述したらよいのでしょうか? 下記のように記載しましたが同じエラーが出てしまい、どうしたらよいかわからず困っています。 setUserName =(data)=>userName=data;
maisumakun

2022/09/22 05:58

setUserNameを関数として呼んでください。
caren

2022/09/22 06:03

setUserName =(data)=>userName=data;と記載していたところを、 setUserName();と書き換えるということでしょうか? そうするとTypeError: r is not a functionというエラーが出てしまいます。
caren

2022/09/22 06:23

すみません、解決しましたのでクローズとさせていただきます。 ありがとうございました。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問