##実現したいこと・質問したいこと
selectedの[]に正しく値を入力したい.
二つ目のコードのpayloadの部分をselectedに追加させて、undefinedを解消させたい。。
どうすればエラーを解消し、追加することが出来るのかを教えていただきたいです。
##エラーメッセージ
Cannot read property 'title' of undefined
##試してみたこと
console.logによって原因を考えました。そうすると、global.selectedが空配列になっているため、titleがundefinedになるのだと思います。なぜ何も値が入っていないのかと思い、その原因をconsole.logで確認したところ、そもそもuseEffectが実行されていないのではないかと思いました。(useEffectの中のconsole.logが実行されていない)
useEffectはVideoDetailコンポーネントがマウントされるときに実行されると思ったのですが、実行されていないということはコンポーネントが配置されていないのでしょうか。
どうすれば解決できるかもご教授いただけると幸いです。
##ソースコード
javascript
1import React, { useEffect, useContext } from 'react'; 2import { useLocation } from 'react-router-dom' 3import { fetchSelectedData } from '../../apis/index' 4import { Store } from '../../store/index' 5import VideoPlay from '../VideoPlay/VideoPlay'; 6import Style from './VideoDetail.module.scss' 7import Linkify from 'react-linkify' 8//useEffect内ではasync 関数を利用することができないので別に関数を用意する 9 10const VideoDetail = () => { 11 const { globalState, setGlobalState } = useContext(Store) 12 const location = useLocation() 13 const setSelectedVideo = async () => { 14 //location.search...URLの?以降が格納されている。これをURLSearchparamsに渡すことでオブジェクトに変更 15 const searchParams = new URLSearchParams(location.search) 16 const id = searchParams.get('v') 17 console.log(searchParams) 18 console.log('id', id) 19 //idはv=という形でURLに含まれているためこれでパラメータを取得する 20 //これが実行されてない可能性あり 21 await fetchSelectedData(id).then((res) => { 22 //このshift()メソッドは、 配列から最初の要素を削除し、その削除された要素を返します。このメソッドは、配列の長さを変更します。 23 const item = res.data.items.shift() 24 setGlobalState({ type: 'SET_SELECTED', payload: { selected: item } }) 25 console.log('res', res) 26 }) 27 } 28 //useEffectすら実行されてない 29 useEffect(() => { 30 setSelectedVideo() 31 console.log(setSelectedVideo()) 32 }, []) 33 console.log(globalState) 34 console.log(globalState.selected) 35 console.log(globalState.selected.id) 36 console.log(globalState.selected.snippet) 37 38 return globalState.selected ? ( 39 <div className={Style.wrap}> 40 <VideoPlay id={globalState.selected.id} /> 41 <p>{globalState.selected.snippet.title}</p> 42 <hr /> 43 <Linkify> 44 <pre>{globalState.selected.snippet.description}</pre> 45 </Linkify> 46 </div> 47 ) : (<span style={{ color: "white" }}>no data</span>) 48} 49 50export default VideoDetail
javascript
1import React, { createContext, useReducer } from 'react'; 2 3const initialState = { 4 popular: [], 5 selected: [] 6} 7//reducer関数は二つの値を取り、一つの値を返す関数のこと 8const reducer = (state, action) => { 9 //そもそもreducerを通しているのか疑惑 10 console.log(action.payload) 11 switch (action.type) { 12 case 'SET_POPULAR': 13 return { ...state, popular: action.payload.popular } 14 case 'SET_SELECTED': 15 //initialStateに複数に配列が含まれる場合、stateを展開していないとpopularのでーたが消えてしまうので 16 return { ...state, selected: action.payload.selected } 17 default: 18 return state; 19 } 20 21} 22//初期値 23export const Store = createContext({ 24 globalState: initialState, 25 setGlobalState: () => null 26}) 27 28export const StoreProvider = ({ children }) => { 29 const [globalState, setGlobalState] = useReducer(reducer, initialState) 30 return ( 31 <Store.Provider value={{ globalState, setGlobalState }}> 32 {children} 33 </Store.Provider> 34 ) 35}
##環境
windows10
react: 17.0.2
あなたの回答
tips
プレビュー