前提
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/ツールのバージョンなど)
ここにより詳細な情報を記載してください。
回答1件
あなたの回答
tips
プレビュー
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
2022/09/22 05:43
2022/09/22 05:58
2022/09/22 06:03
2022/09/22 06:23