現在、Next.jsを基盤にreact-reduxで状態管理するアプリケーションを作成しています。
以下のコードについて説明いたします。
- Results.jsでstoreにconnectし、APIから取得済みのitemsを子コンポーネントであるListItem.jsを用いてリスト表示
- ListItemにある保存ボタンをクリックするとコールバック関数であるhandleClickを通じてtoggleBookmarkをdispatchし、itemのプロパティーであるis_bookmarked(Boolean)を変更する
javascript
1 2// items 3 4[ 5 {id: 1, title: 'title1', is_bookmarked: true}, 6 {id: 2, title: 'title2', is_bookmarked: false} 7] 8 9// components/molecules/ListItem.js 10 11const ListItem = React.memo(({ item, handleClick }) => { 12 return ( 13 <div> 14 <p>{item.title}</p> 15 <button onClick={handleClick}> 16 {item.is_bookmarked ? '保存済み' : '保存する'} 17 </button> 18 </div> 19 ) 20}) 21 22export default ListItem 23 24// components/organisms/Results.js 25 26const Search = ({ items, toggleBookmark }} => { 27 return items.map(item => ( 28 <ListItem 29 key={item.id} 30 item={item} 31 handleClick={() => toggleBookmark(item.id)} 32 /> 33 )) 34} 35 36const mapStateToProps = (state) => ({ 37 items: state.classified.items, 38}) 39 40const mapDispatchToProps = (dispatch) => { 41 return { 42 toggleBookmark: bindActionCreators(toggleBookmark, dispatch) 43 } 44} 45 46export default connect(mapStateToProps, mapDispatchToProps)(Results) 47 48// reducer.js 49 50export default function reducer(state = [], action) { 51 switch (action.type) { 52 case actionTypes.TOGGLE_BOOKMARK: 53 return { 54 ...state, 55 items: state.items.map(el => el.id === action.payload ? { ...el, is_bookmarked: !el.is_bookmarked } : el) 56 } 57 default: 58 return state 59 } 60}
上記は可能な限りAtomic designに沿って作成したため、molecules内にあるListItemではロジックを記述せず、上層のorganismsにあるResultsにてconnect、またロジックの記述をしています。(説明のためatomsをmoleculesにまとめて記載、またcontainerとpresentationalに分けずまとめて記載しています)
この状態でreact devtoolsにあるHighlight Updateをチェックし、任意のListItemの保存ボタンをクリックすると、クリックされたボタンのあるコンポーネントだけでなく、それ以外の全てのListItemが再レンダリングされるのが確認できます。
ここで質問です。
0. クリックされたボタンのあるコンポーネントのみを再レンダリングしたい場合、どのような方法をとるべきなのでしょうか?
0. 上記の実装において問題点はありますか?
例えばResultsではなくListItemでconnectした場合は、当然ですがボタン押下時に対象のコンポーネントのみが再レンダリングされました。しかしAtomic Designの観点等からconnectするのはorganisms以上のコンポーネントでするべきだと認識しているので、それは避けたいです。
親コンポーネントでconnectし、そこからstateやコールバック関数を子コンポーネントに渡す限り、上記コードにおける親に付随する全子コンポーネントの再レンダリングは免れないのでしょうか?
回答1件
あなたの回答
tips
プレビュー
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
2020/07/10 01:23
2020/07/10 01:27
2020/07/10 01:44
2020/07/11 13:20