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

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

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

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

Q&A

解決済

2回答

605閲覧

propsを用いて子コンポーネントから 親コンポーネントへデータを渡したい

Tomato_leaf

総合スコア173

React.js

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

0グッド

1クリップ

投稿2023/01/27 08:06

前提

タグを追加できる子コンポーネントTagsInput.jsから
propsを用いて親コンポーネントTop.jsへデータを渡そうとしていますが
エラーの原因がわかりません。。

実現したいこと

propsを用いて子コンポーネントのTagsInput.jsから
親コンポーネントTop.jsへデータを渡したい

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

props.setTagsinput is not a function

イメージ説明

該当のソースコード

TagsInput.js

1 2 3import React from "react"; 4 5const TagsInput = (props) => { 6 7 //1, Define the tags variable to store the entered tags. (I want to pass the value of the tags variable to the parent component Top.js) 8 const [tags, setTags] = React.useState([]); 9 10 //2, Put formText in the function received from the parent component and return it. 11 props.setTagsinput(tags); 12 console.log(props) 13 14 let tag_list = [] 15 tag_list.push(tags); 16 17 18 const addTags = event => { 19 if (event.key === "Enter" && event.target.value !== "") { 20 setTags([...tags, event.target.value]); 21 event.target.value = ""; 22 } 23 }; 24 const removeTags = index => { 25 setTags([...tags.filter(tag => tags.indexOf(tag) !== index)]); 26 }; 27 28 return ( 29 <div className="tags-input"> 30 <div className="tags_section"> 31 {tags.map((tag, index) => ( 32 <div className="tag tag-flex" key={index}> 33 <p className="tag-p">{tag}</p> 34 </div> 35 ))} 36 </div> 37 <input 38 type="text" 39 onKeyUp={event => addTags(event)} 40 placeholder="Press enter to add tags" 41 /> 42 </div> 43 ); 44}; 45export default TagsInput;

Top.js

1import TagsInput from "./TagsInput"; 2 3const Top = () => { 4 5 6 //Declare the tags_from_tagsinput variable that receives the tags variable received from the child component 7 const[tags_from_tagsinput, setTagsinput]= useState(""); 8 console.log(tags_from_tagsinput); 9 10 11 12 13 return ( 14 <div> 15 16 </div> 17 ); 18} 19export default Top; 20

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

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

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

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

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

uky

2023/01/27 08:12

TagsInputはどこで利用しているのでしょうか? Topでインポートしているだけに見えます
Tomato_leaf

2023/01/27 10:20

すいません、Student.jsというコンポーネントが抜けていました。。。解決済みコードをアップさせていただきました!
guest

回答2

0

Reactの特徴の一つとして、単方向データフローというものがあります。
端的に紹介すると、親から子へのデータのやり取りしか行わないと言うものです。(参考のステップ4に記載があります。

もし親でデータを使いたいのであれば、参考のステップ5のように、書く必要があります。
※ 参考リンクをステップ1から一通り読むことで悩みを解消できると思います。

エラー自体は以下のように書けば解消されると思います。

jsx

1import TagsInput from "./TagsInput"; 2 3// Top 4const Top = () => { 5 const[tags_from_tagsinput, setTagsinput]= useState(""); 6 7 return ( 8 <TagsInput setTagsInput={setTagsinput} /> 9 ); 10} 11export default Top; 12 13 14// TagsInput 15const TagsInput = ({ setTagsInput }) => { 16 // 省略 17}; 18export default TagsInput; 19

投稿2023/01/27 08:23

編集2023/01/27 08:45
uky

総合スコア207

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

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

Tomato_leaf

2023/01/27 10:20

ありがとうございます。すいません、解決済みコードをアップさせていただきました!
uky

2023/01/27 10:23

解決したようで何よりです!
guest

0

自己解決

Top.js

1import React, { useState, useEffect } from "react"; 2import axios from "axios"; 3import Student from "./Student"; 4import TagsInput from "./TagsInput"; 5 6const Top = () => { 7 const [posts, setPosts] = useState([]); 8 const [allPosts, setAllPosts] = useState([]); 9 10 let tag_list = []; 11 const [searchKeyword, setSearchKeyword] = React.useState(""); 12 const [searchTagKeyword, setTagSearchKeyword] = React.useState(""); 13 console.log(searchKeyword); 14 15 const [tags_from_tagsinput, setTagsinput] = useState(""); 16 console.log(tags_from_tagsinput); 17 18 useEffect(() => { 19 axios.get("xxx.com").then((result) => { 20 setPosts(result.data.students); 21 setAllPosts(result.data.students); 22 if (searchKeyword) { 23 getSearchResult(); 24 } 25 }); 26 }, [searchKeyword]); 27 28 const getSearchResult = () => { 29 console.log(searchKeyword); 30 const result = allPosts.filter((output, index) => { 31 return ( 32 output.firstName.toLowerCase().includes(searchKeyword.toLowerCase()) || 33 output.lastName.toLowerCase().includes(searchKeyword.toLowerCase()) 34 ); 35 }); 36 console.log(result); 37 setPosts(result); 38 }; 39 40 const getTagSearchResult = () => { 41 console.log(searchTagKeyword); 42 const result = allPosts.filter((output, index) => { 43 return output.lastName 44 .toLowerCase() 45 .includes(searchTagKeyword.toLowerCase()); 46 }); 47 console.log(result); 48 setPosts(result); 49 }; 50 51 const setTagsFromStudent = (tags) => { 52 setTagsinput(tags); 53 }; 54 55 return ( 56 <div> 57 <div> 58 <input 59 className="search-box" 60 placeholder="" 61 value={searchKeyword} 62 onChange={(e) => setSearchKeyword(e.target.value)} 63 /> 64 </div> 65 <div> 66 <input 67 className="search-box" 68 placeholder="" 69 value={searchTagKeyword} 70 onChange={(e) => setSearchKeyword(e.target.value)} 71 /> 72 </div> 73 <div> 74 {searchKeyword && <p>{searchKeyword} Search</p>} 75 {posts ? ( 76 <> 77 {posts.map((data, i) => ( 78 <Student data={data} setStudentTags={setTagsFromStudent} /> 79 ))} 80 </> 81 ) : ( 82 <div> 83 <p>Not Found!</p> 84 </div> 85 )} 86 </div> 87 </div> 88 ); 89}; 90export default Top;

TagsInput.js

1import React from "react"; 2 3const TagsInput = (props) => { 4 const [tags, setTags] = React.useState([]); 5 6 let tag_list = []; 7 tag_list.push(tags); 8 9 const addTags = (event) => { 10 if (event.key === "Enter" && event.target.value !== "") { 11 setTags([...tags, event.target.value]); 12 // call function pass down from toptag 13 props.setStudentTags(tags); 14 event.target.value = ""; 15 } 16 }; 17 const removeTags = (index) => { 18 setTags([...tags.filter((tag) => tags.indexOf(tag) !== index)]); 19 }; 20 21 return ( 22 <div className="tags-input"> 23 <div className="tags_section"> 24 {tags.map((tag, index) => ( 25 <div className="tag tag-flex" key={index}> 26 <p className="tag-p">{tag}</p> 27 </div> 28 ))} 29 </div> 30 <input 31 type="text" 32 onKeyUp={(event) => addTags(event)} 33 placeholder="Press enter to add tags" 34 /> 35 </div> 36 ); 37}; 38export default TagsInput;

Student.js

1import React, { useState } from "react"; 2import TagsInput from "./TagsInput"; 3const Student = (props) => { 4 const [show, setShow] = useState(false); 5 6 const gradesAverage = (grades) => { 7 let sum = 0; 8 grades.forEach(function (score) { 9 sum += Number(score); 10 }); 11 let ave = sum / grades.length; 12 return ave; 13 }; 14 15 return ( 16 <div className="flex"> 17 <div className="image"> 18 <img src={props.data.pic} className="profile" /> 19 </div> 20 <div> 21 <p className="name"> 22 {props.data.firstName} {props.data.lastName} 23 </p> 24 <button className="button" onClick={() => setShow(!show)}> 25 {show ? ( 26 <div className="button_p">-</div> 27 ) : ( 28 <div className="button_p">+</div> 29 )} 30 </button> 31 <div className="info"> 32 <p>Email: {props.data.email}</p> 33 <p>Company: {props.data.company}</p> 34 <p>Skill: {props.data.skill}</p> 35 <p>Average Grade: {gradesAverage(props.data.grades)}%</p> 36 {show && ( 37 <> 38 <p>Test 1: {props.data.grades[0]}%</p> 39 <p>Test 2: {props.data.grades[1]}%</p> 40 <p>Test 3: {props.data.grades[2]}%</p> 41 <p>Test 4: {props.data.grades[3]}%</p> 42 <p>Test 5: {props.data.grades[4]}%</p> 43 <p>Test 6: {props.data.grades[5]}%</p> 44 <p>Test 7: {props.data.grades[6]}%</p> 45 <p>Test 8: {props.data.grades[7]}%</p> 46 </> 47 )} 48 {/*pass settag from topTag component*/} 49 <TagsInput setStudentTags={props.setStudentTags} /> 50 </div> 51 </div> 52 </div> 53 ); 54}; 55export default Student;

上記のコードでうまくいきました!

投稿2023/01/27 10:19

Tomato_leaf

総合スコア173

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

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

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.50%

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

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

質問する

関連した質問