前提・実現したいこと
ここに質問の内容を詳しく書いてください。
(例)JavaScript(React/Redux)とSpring MyBatisで民泊サイト的なシステムを作っています。
クライアントサイド側で入力された情報をDBに挿入する機能を実装中に以下のエラーメッセージが発生しました。
発生している問題・エラーメッセージ
JavaScript
1Uncaught TypeError: Cannot read property 'innId' of undefined
該当のソースコード(1部抜粋)
民泊の絞り込み検索をする機能(components/InnList)
JavaScript
1const InnList = (props) => { 2 const {classes} = props; 3 return ( 4 <List> 5 <p>施設レビュー数…施設利用者による施設レビューの掲載数です。</p> 6 <p>第三者評価数…行政や企業などの認可された団体がおすすめしているコメントの掲載数です。</p> 7 {props.inns.filter((inn) => inn.prefecture.id === props.prefecture).map((inn) => { 8 return( 9 <ListItem key={inn.id} divider={true}> 10 <Avatar alt='Remy Sharp' src={inn.url}/> 11 <ListItemText primary={inn.name} secondary={inn.address}/> 12 <ListItemText primary={'最大宿泊人数'} secondary={inn.numOfPeople + '人'}/> 13 <ListItemText primary={'値段'} secondary={inn.price + '円'}/> 14 <ListItemText primary={'施設レビュー数'} secondary={inn.countReview + '件'}/> 15 <ListItemText primary={'第三者評価数'} secondary={inn.countEvaluation + '件'}/> 16 <Button 17 variant='raised' 18 color='primary' 19 className={classes.button} 20 onClick={(event) => { 21 props.openMessage(inn.id) 22 }}> 23 この施設を予約 24 </Button> 25 </ListItem> 26 ); 27 }) 28 } 29 </List> 30 ); 31}; 32export default withStyles(styles)(InnList);
reservation/actionCreators
JavaScript
1export const openMessage = (innId) => { 2 return { 3 type: ACTION_MESSAGE_OPEN, 4 innId: innId 5 }; 6};
reservation/actionTypes
JavaScript
1/* 2 * メッセージダイアログに関するアクションタイプ 3 */ 4 5export const ACTION_MESSAGE_OPEN = 'ACTION_MESSAGE_OPEN';
reservation/reducers
JavaScript
1 //ユーザ情報の一時格納 2 userInfo: { 3 username: { 4 value: '', 5 }, 6 name: { 7 value: '', 8 isError: false, 9 }, 10 innId:{ 11 value:'', 12 }, 13 numOfPeople: { 14 value: '', 15 isError: false, 16 }, 17 tel: { 18 value: '', 19 isError: false, 20 }, 21 checkIn: { 22 value: '', 23 isError: false, 24 }, 25 checkOut: { 26 value: '', 27 isError: false, 28 }, 29 comment: { 30 value: '', 31 isError: false, 32 } 33 }, 34}; 35 36 37export const openMessage = (state, action) => { 38 return Object.assign({}, state, { 39 messageStatus: true, 40 userInfo: Object.assign({}, state.userInfo, { 41 innId: Object.assign({}, state.userInfo.innId, { 42 innId: action.innId} 43 ) 44 }) 45 }) 46}
(合計3つを統合する為の)./reducers
JavaScript
1/* Redux関連 */ 2import {combineReducers} from 'redux'; 3/* リデューサー */ 4import accountReducer from './account/reducers'; 5import innsReducer from './inns/reducers'; 6import reservationReducer from './reservation/reducers'; 7 8/* リデューサーを統合して公開 */ 9export default combineReducers({ 10 account: accountReducer, 11 inns: innsReducer, 12 messagedialog: reservationReducer 13});
containers
JavaScript
1/** 2 * MessageDialog 3 */ 4export const MessageDialog = connect( 5 (state) => ({ 6 account: state.app.account, 7 inns: state.app.inns.inns, 8 message: state.app.messagedialog 9 }), 10 (dispatch) => { 11 const messageActionCreators = bindActionCreators(_messageActionCreators, dispatch); 12 const jumpTopPage = bindActionCreators(push,dispatch); 13 return { 14 closeMessage: messageActionCreators.closeMessage, 15 closeConfirmation: messageActionCreators.closeConfirmation, 16 openConfirmation: messageActionCreators.openConfirmation, 17 openComp: messageActionCreators.openComp, 18 closeComp: messageActionCreators.closeComp, 19 jumpTopPage: jumpTopPage, 20 userUpdate: messageActionCreators.userUpdate, 21 postReservation: messageActionCreators.postReservation, 22 openMessage: messageActionCreators.openMessage 23 } 24 } 25 26)(_MessageDialog);
JavaScript
1class MessageDialog extends React.Component { 2 3 constructor(props) { 4 super(props); 5 6 this.state = { 7 8 open: false, 9 userInfo: { 10 username: { 11 value: '', 12 }, 13 name: { 14 value: '', 15 isError: false, 16 }, 17 innId:{ 18 value:'', 19 }, 20 numOfPeople: { 21 value: '', 22 isError: false, 23 }, 24 tel: { 25 value: '', 26 isError: false, 27 }, 28 checkIn: { 29 value: '', 30 isError: false, 31 }, 32 checkOut: { 33 value: '', 34 isError: false, 35 }, 36 comment: { 37 value: '', 38 isError: false, 39 } 40 }, 41 }; 42 } 43 44 45 handleNameChange (event) { 46 const name = event.target.value; 47 const userInfo = Object.assign({}, this.state.userInfo, { 48 name: Object.assign({}, this.state.userInfo.name, { 49 value: name, 50 isError: !event.target.validity.valid 51 }) 52 }); 53 this.setState({userInfo: userInfo}); 54 } 55 handleNumChange (event) { 56 const numOfPeople = event.target.value; 57 let error = false; 58 if (numOfPeople === '') 59 error = true; 60 61 const userInfo = Object.assign({}, this.state.userInfo, { 62 numOfPeople: Object.assign({}, this.state.userInfo.numOfPeople, { 63 value: numOfPeople, 64 isError: error 65 }) 66 }); 67 this.setState({userInfo: userInfo}); 68 } 69 handleTelChange (event) { 70 const tel = event.target.value; 71 const userInfo = Object.assign({}, this.state.userInfo, { 72 tel: Object.assign({}, this.state.userInfo.tel, { 73 value: tel, 74 isError: !event.target.validity.valid 75 }) 76 }); 77 this.setState({userInfo: userInfo}); 78 } 79 handleCheckInChange (event) { 80 const checkIn = event.target.value; 81 const userInfo = Object.assign({}, this.state.userInfo, { 82 checkIn: Object.assign({}, this.state.userInfo.checkIn, { 83 value: checkIn, 84 isError: !event.target.validity.valid 85 }) 86 }); 87 this.setState({userInfo: userInfo}); 88 } 89 handleCheckOutChange (event) { 90 const checkOut = event.target.value; 91 const userInfo = Object.assign({}, this.state.userInfo, { 92 checkOut: Object.assign({}, this.state.userInfo.checkOut, { 93 value: checkOut, 94 isError: !event.target.validity.valid 95 }) 96 }); 97 this.setState({userInfo: userInfo}); 98 } 99 handleCommentChange (event) { 100 const comment = event.target.value; 101 const userInfo = Object.assign({}, this.state.userInfo, { 102 comment: Object.assign({}, this.state.userInfo.comment, { 103 value: comment, 104 }) 105 }); 106 107 this.setState({userInfo: userInfo}); 108 } 109 110 static getDerivedStateFromProps(props, state) { 111 if (props.message.userInfo.innId.value !== '') { 112 return Object.assign({}, state, { 113 userInfo: Object.assign({}, state.userInfo, { 114 innId: Object.assign({}, state.userInfo.innId, { 115 value: props.message.userInfo.innId.value 116 }) 117 }) 118 }) 119 } 120 if (props.account.claims !== null && props.account.claims.sub !== '') { 121 return Object.assign({}, state, { 122 userInfo: Object.assign({}, state.userInfo, { 123 username: Object.assign({}, state.userInfo.username, { 124 value: props.account.claims.sub 125 }) 126 }) 127 }) 128 } 129 return state; 130 131 };
試したこと
・Google ChromeのDevToolsを使ってエラーがどのタイミングで発生するのか確認しました。
1)InnListコンポーネントで「この施設を予約する」ボタンを押すと、openMessage関数が引数「inn.id(例えば3)」を持った状態で呼び出されます。
*innsはサーバーサイドからfetch関数で受け取った配列です。
2)/reservation/actionCreatorsのopenMessage関数に引数としてinnIdに「3」という数字が渡されている。
3)/reservation/reducersのデバック時にactionとして渡されているはずの「innId」がなぜかundefinedになっている。
* 「redux.js」というクラスの
JavaScript
1try { 2 isDispatching = true; 3 currentState = currentReducer(currentState, action); 4 } finally { 5 isDispatching = false; 6 }
の時点ではまだcurrentStateとして「type:ACTION_MESSAGE_OPEN, innId:3」は存在します。この後reducersに移る時、なぜかactionがundefinedになってしまいます。
補足情報(FW/ツールのバージョンなど)
propsのinnIdが認識されないのがなぜか解明したいです。
足りないコードがあれば言ってください。よろしくお願いします。
回答1件
あなたの回答
tips
プレビュー