前提・実現したいこと
Ruby on Rails×ReactでWebアプリケーションを作成しています。
元々Reactでコンポーネントを細かく分けずに実装していたのですが、見通しをよくするため適切に分けようとしていたところ、意図しない動きになったため質問させていただきます。
ECサイトのようなWebアプリケーションで、商品の一覧と商品の詳細ダイアログが表示され、ダイアログ上で個数を変更できるようにしていますが、コンポーネントを分けたところ、個数を変更するたびにダイアログが再レンダリングされてしまい、UXとして良くない状態になってしまいました。
利用技術
- Ruby on Rails
- React
- Material-UI
- TypeScript
コード比較
元々のコード(意図する動きを実現)
index.jsx
React
1const UserManagementsMenu: React.FC<Props> = (props: Props) => { 2 const classes = useStyles() 3 4 5 const handleItemCount = (counter: boolean) => { 6 const newCount = 0 7 if (counter == true) { 8 setItemCount(itemCount + 1) 9 setSwitchDeleteButton(true) 10 } else { 11 if (itemCount > 2) { 12 setItemCount(itemCount - 1) 13 } else { 14 if (itemCount == 2) { 15 setItemCount(itemCount - 1) 16 } 17 setSwitchDeleteButton(false) 18 } 19 } 20 } 21 22return ( 23 <ThemeTemplate> 24 <Container> 25 //商品一覧のコードベタがき (省略) 26 27 //商品の詳細のDialogベタがき (簡素化しています) 28 <Dialog> 29 <DialogContent> 30 <Card> 31 <CardContent> 32 </CardContent> 33 <CardActions> 34 <Grid container spacing={3}> 35 <Grid item xs={3}> 36 <div > 37 <IconButton 38 onClick={() => handleItemCount(false)}> 39 </IconButton> 40 </div> 41 </Grid> 42 <Grid item xs={3}> 43 <div> 44 <Button aria-label="previous"> 45 <Typography> 46 {itemCount} 47 </Typography> 48 </Button> 49 </div> 50 </Grid> 51 <Grid item xs={3}> 52 <div className={classes.controls}> 53 <IconButton onClick={() => handleItemCount(true)}> 54 </IconButton> 55 </div> 56 </Grid> 57 </Grid> 58 </CardActions> 59 </Card> 60 </DialogContent> 61 </dialog> 62 </Container> 63 </ThemeTemplate> 64
コンポーネントを分けたコード(意図しない動きになった)
index.jsx
React
1//import系を全てここに記載 2import * as React from "react" 3import {useState, useEffect, createRef} from "react" 4省略 5 6 7//Propsをここに全て記載 8type Props = { 9 shop: { 10 id: number 11 name: string 12 } 13 省略 14 } 15 16 17//CSS系はここに記載 18const useStyles = makeStyles((theme: Theme) => 19 createStyles({ 20 root: { 21 padding: theme.spacing(1, 2, 1), 22 margin: theme.spacing(7, 0, 5), 23 }, 24 省略 25 }) 26 ) 27 28 29 30//以下 UserManagementsMenuの中身, このViewの主な要素はこの中に記載 31const UserManagementsMenu: React.FC<Props> = (props: Props) => { 32 const classes = useStyles() 33 34 //hooks系もここに全て記載 35 const [name, setName] = useState(String) 36 const [openItemDialog, setOpenItemDialog] = useState(false) 37 省略 38 39 40 41 const handleItemCount = (counter: boolean) => { 42 const newCount = 0 43 if (counter == true) { 44 setItemCount(itemCount + 1) 45 setSwitchDeleteButton(true) 46 } else { 47 if (itemCount > 2) { 48 setItemCount(itemCount - 1) 49 } else { 50 if (itemCount == 2) { 51 setItemCount(itemCount - 1) 52 } 53 setSwitchDeleteButton(false) 54 } 55 } 56 } 57 58//他handlerも同様に記載、これらは変更していない 59 60 61 62//以下、複数の分けたコンポーネントをここに記載, 全てUserManagementsMenuの中に存在 63//変更している箇所はここのみ 64 const ItemList =() => { 65 const classes = useStyles() 66 return ( 67 省略 68 ) 69 } 70 71 72 const ItemDetailDialog =() => { 73 const classes = useStyles() 74 return ( 75 <> 76 <Dialog> 77 <DialogContent> 78 <Card> 79 <CardContent> 80 </CardContent> 81 <CardActions> 82 <Grid container spacing={3}> 83 <Grid item xs={3}> 84 <div > 85 <IconButton onClick={() => handleItemCount(false)}> 86 </IconButton> 87 </div> 88 </Grid> 89 <Grid item xs={3}> 90 <div> 91 <Button aria-label="previous"> 92 <Typography> 93 {itemCount} 94 </Typography> 95 </Button> 96 </div> 97 </Grid> 98 <Grid item xs={3}> 99 <div className={classes.controls}> 100 <IconButton onClick={() => handleItemCount(true)}> 101 </IconButton> 102 </div> 103 </Grid> 104 </Grid> 105 </CardActions> 106 </Card> 107 </DialogContent> 108 </dialog> 109 </> 110 ) 111 } 112 113 114 115//ここでそれぞれのコンポーネントを呼び出している 116 return ( 117 <ThemeTemplate> 118 <Container> 119 <ItemList/> 120 <ItemDetailDialog/> 121 </Container> 122 </ThemeTemplate> 123 ) 124} 125 126//ここまでがUserManagementsShopMenu: React.FC<Props> の中身 127 128export default UserManagementsMenu 129//ここで終わり
発生している問題
onClick
イベントが発生した際に、ItemDetailDialogコンポーネント
が再レンダリングされてしまいます。元々のコードでは、再レンダリングされず、onclick
で個数を変更した時は、Dialogはそのままで個数の表示だけ変えることができました。
コンポーネントは、分けても同じ1ファイルに記述しています。
コンポーネントを分けた以外には何も追加したり消したりしていません。
試したこと
Reactの基本的なところかと思うのですが、これまでちゃんとコンポーネントを分けて開発していなかったため、この事象を解決できずにいます。。お教えいただけますと嬉しいです。
補足情報(FW/ツールのバージョンなど)
ここにより詳細な情報を記載してください。
あなたの回答
tips
プレビュー