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

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

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

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

Q&A

解決済

1回答

1238閲覧

親コンポーネントから受け取ったDateオブジェクトが意図した値にならない

Kino104

総合スコア10

React.js

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

0グッド

0クリップ

投稿2021/08/13 07:55

実現したいこと

Reactでカレンダーを作っています。
カレンダーの日付を割り当てるためのプログラムを作っているのですが、意図した日付の値にならない為、質問させていただきます。

ソースコード

React

1import './App.css'; 2import DateBox from './components/DateBox'; 3import Nav from "./components/Nav"; 4import styled from 'styled-components'; 5import { useState } from 'react'; 6 7 8 9function App() { 10 11 // styled-components → 12 const Container = styled.div` 13 margin: 10px; 14 `; 15 16 const DatesUl = styled.ul` 17 display: grid; 18 grid-template-columns: repeat(7, 1fr); 19 border: 1px solid rgba(0, 0, 0, 0.54); 20 border-bottom: none; 21 border-right: none; 22 padding: 0; 23 `; 24 // ← styled-components 25 26 const [dates, setDates] = useState(new Date()); 27 const days = []; 28 const weeks = ["日", "月", "火", "水", "木", "金", "土"]; 29 let nowYear = dates.getFullYear(); 30 let nowMonth = dates.getMonth() + 1; 31 let firstDate = new Date(nowYear, (nowMonth-1), 1); 32 let firstDay = firstDate.getDay(); 33 let startDate = new Date(firstDate); 34 startDate.setDate(firstDate.getDate() - firstDay); 35 for(let i = 0; i < 35; i++) { 36 if (i < 7) { 37 console.log(startDate); 38 days.push(<DateBox topDays="true" week={weeks[i]} date={startDate} />); 39 } else { 40 console.log(startDate); 41 days.push(<DateBox date={startDate} />); 42 } 43 startDate.setDate(startDate.getDate() + 1); 44 } 45 46 const changeMonth = (key) => { // 月移動関数 47 if (key === "prev") { 48 let newDates = new Date(dates.setMonth(dates.getMonth() - 1)); 49 setDates(newDates); 50 } else if (key === "next") { 51 let newDates = new Date(dates.setMonth(dates.getMonth() + 1)); 52 setDates(newDates); 53 } 54 } 55 56 57 return ( 58 <Container> 59 <Nav dates={dates} changeMonth={changeMonth} /> 60 <DatesUl> 61 {days} 62 </DatesUl> 63 </Container> 64 ); 65} 66 67export default App;

React

1import styled from 'styled-components'; 2 3const DateBox = (props) => { 4 5 // styled-components → 6 const DateLi = styled.li` 7 list-style: none; 8 height: 120px; 9 border-bottom: 1px solid rgba(0, 0, 0, 0.54); 10 border-right: 1px solid rgba(0, 0, 0, 0.54); 11 @media(min-width: 600px) { 12 height: 155px; 13 } 14 `; 15 16 const Day = styled.div` 17 text-align: center; 18 color: rgba(0, 0, 0, 0.54); 19 margin-top: 5px; 20 font-size: 12px; 21 `; 22 23 const Date = styled.div` 24 text-align: center; 25 margin-top: 5px; 26 font-size: 12px; 27 `; 28 // ← styled-components 29 30 31 return( 32 <DateLi> 33 {props.topDays ? 34 <> 35 <Day>{props.week}</Day> 36 <Date>{props.date.getDate()}</Date> 37 </> : 38 <Date>{props.date.getDate()}</Date> 39 } 40 </DateLi> 41 ); 42} 43 44export default DateBox;

問題部分

DateBoxコンポーネントのprops.date.getDate()の値が全て5になってしまいます。

Appコンポーネントのdays.push(<DateBox topDays="true" week={weeks[i]} date={startDate} />);の部分のdate={startDate}date={startDate}に変更し、
DateBoxコンポーネントの props.date.getDate()props.dateに変更すると意図した値に表示されますが、Dateオブジェクトをpropsとして渡したいため、困っています。

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

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

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

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

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

guest

回答1

0

ベストアンサー

startDate.setDateは、Dateオブジェクトを破壊的に変更します。同じDateオブジェクトをすべてのDateBoxへ供給している形となっています。

ループ1回毎にnew Dateで新しいDateオブジェクトを作り、それを渡しましょう。

投稿2021/08/13 08:08

maisumakun

総合スコア145184

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

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

maisumakun

2021/08/13 08:10 編集

> Dateオブジェクトをpropsとして渡したいため、困っています。 このように「うっかり破壊的に変更してしまう」ような状況であれば、Dateとして渡さないほうがいいかもしれません。propとしては文字列で渡して、コンポーネント内部で必要に応じてnew Dateを行ったほうが、不意に破壊的変更をするリスクも減り安全です。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問