ã«ã«ã¼ã»ã«ã¨ã横並ã³ã®è¦ç´ ã®é«ããReactã§æããããããªå ´å (display: flex
ã使ããªããããªã±ã¼ã¹)
è¦ç´ ã®ããããã®DOMã«ã¢ã¯ã»ã¹ãã¦é«ããåå¾ãã¦æãé«ããã®ãåå¾ããªããã°ãªããªãã®ã§ããªã¹ãã®ãã㪠Ref ãå¿
è¦ã«ãªãã¾ãã
ã¾ããã¦ã£ã³ãã¦ãµã¤ãºãå¤ãã£ãæã«åè¨ç®ããå¿
è¦ãããã®ã§ã resize
ã¤ãã³ãã§æ大å¤ã®åè¨ç®ãããå¿
è¦ãããã¾ãã
useRef ã§è¤æ°ã®è¦ç´ ã« ref ã渡ã
DOMã¸ã®ã¢ã¯ã»ã¹ã¯ RefObject
ãéãã¦ã¢ã¯ã»ã¹ã§ãã¾ããããªã¹ãè¦ç´ ããããã®DOMã«ã¢ã¯ã»ã¹ãããã¨ãªãã¨ãããããã« ref
ã渡ãå¿
è¦ãããã¾ãã
import React, { useState, useRef, createRef } from 'react'; function Carousel({ initItems }) { const [items, setItems] = useState(initItems); // current ã« refObject ã®å ¥ã£ãé åãä½æãã const itemsRef = useRef( [...Array(items.length)].map(() => createRef) ); const carouselItems = items.map(({id, ...props}, i) => { return ( <CarouselItem key={id} ref={itemsRef.current[i]} {...props} /> ); }); return ( <div className="carousel"> {carouselItems} </div> ); }
ref 㧠DOMã«ã¢ã¯ã»ã¹ãã¦æ大å¤ã®é«ããè¨å®ãã
itemsRef.current
ã reduce
ã§åãã¦ä¸çªå¤§ããªå¤ãåå¾ãã¦ããããã®DOMã«ãããè¨å®ããã°OK
import React, { useState, useEffect, useCallback, useRef, createRef } from 'react'; function Carousel({ initItems }) { const [items, setItems] = useState(initItems); const itemsRef = useRef( [...Array(items.length)].map(() => createRef) ); const getMaxHeight = useCallback((refList) => { return refList.reduce((maxHeight, ref) => { if ( !ref.current ) { return maxHeight; } const itemHeight = ref.current.offsetHeight; return Math.max(itemHeight, maxHeight); }, 0); }, []); const setMaxHeight = useCallback(() => { itemRefs.current.forEach((ref) => { if (ref.current) { ref.current.removeAttribute('style'); } }); const max = getMaxHeight(itemRefs.current); if ( max ) { itemRefs.current.forEach((ref) => { ref.current.style.height = `${max}px`; }); } }, [itemRefs]); // ååã¬ã³ãã¼æã«é«ããæããå¦çãå®è¡ãã useEffect(() => { setMaxHeight(); }, []); //... return (...); }
window resize æã«ãé«ããæããå¦çãå®è¡ãã
resize ã¤ãã³ããèµ·ãã度ã«å¦çããã¦ããã¨å¦çãéããªãã®ã§ debounce ã§å®è¡ãã
cf.
ä»åã¯é¢æ°ãå®è¡ããã ãã§ãå¤ãè¿ãå¿
è¦ããªãã®ã§ãuseDebounceFn
ã¨ãã custom hook ãä½æãã¾ãã
// useDebounceFn.js import { useRef, useCallback } from 'react'; const useDebounceFn = (fn, delay = 100) => { const timer = useRef(null); const dispatch = useCallback((_val) => { timer.current && clearTimeout(timer.current); timer.current = setTimeout(() => { fn(_val); }, delay); }, [fn, delay, timer]); return [dispatch]; }; export useDebounceFn;
window resize ã¤ãã³ã㯠useEffect
å
ã§è¨å®ãã¦ãã³ã³ãã¼ãã³ãã unmount ãããæã«ã¤ãã³ããå¤ããããã« clean up ã®å¦çã return ããããã«ãã¾ãã
import React, { useState, useEffect, useCallback, useRef, createRef } from 'react'; import { useDebounceFn } from './useDebounceFn'; function Carousel({ initItems }) { const [items, setItems] = useState(initItems); const itemsRef = useRef( [...Array(items.length)].map(() => createRef) ); const getMaxHeight = useCallback((refList) => { return refList.reduce((maxHeight, ref) => { if ( !ref.current ) { return maxHeight; } const itemHeight = ref.current.offsetHeight; return Math.max(itemHeight, maxHeight); }, 0); }, []); const setMaxHeight = useCallback(() => { itemRefs.current.forEach((ref) => { if (ref.current) { ref.current.removeAttribute('style'); } }); const max = getMaxHeight(itemRefs.current); if ( max ) { itemRefs.current.forEach((ref) => { ref.current.style.height = `${max}px`; }); } }, [itemRefs]); // resize æã« debounce ã§å®è¡ããã¤ãã³ã const [onResizeHandler] = useDebounceFn(setMaxHeight); useEffect(() => { window.addEventListener('resize', onResizeHandler); setMaxHeight(); // unmount æã«å®è¡ããå¦ç return () => window.removeEventListener('resize', onResizeHandler); }, []); //... return (...); }
sample
ð window.resize ãããã®ã§å¥ã¿ãã¨ãã§éãã¦ã¿ã¦ãã ãã
https://codepen.io/kikiki_kiki/pen/povxxeN
ã
useRef
ã¯è²ããªãã®ãå
¥ãããç®±ã ã¨èªèãã¦ããã©ããã®ä¸ã«é
å㧠ref
ãå
¥ããã°ã«ã¼ãã§åºåãããããªã³ã³ãã¼ãã³ãã«ã ref ã渡ããã£ã¦ã®ã«æ°ã¥ãã®ãé£ããã£ã
[åè]
- javascript - How can I use multiple refs for an array of elements with hooks? - Stack Overflow
- https://usehooks.com/useWindowSize/
- useEffect | ãã㯠API ãªãã¡ã¬ã³ã¹ â React
- Array.prototype.reduce() - JavaScript | MDN
- HTMLElement.offsetHeight - Web API | MDN
- LoremFlickr: free placeholder images
- Lorem Picsum
ã¢ã¤ã«ã!ã·ãªã¼ãº 5thãã§ã¹ãã£ãã«!! Day1 Blu-ray
- åºç社/ã¡ã¼ã«ã¼: ã©ã³ãã£ã¹
- çºå£²æ¥: 2019/07/03
- ã¡ãã£ã¢: Blu-ray
- ã¢ã¼ãã£ã¹ã:AIKATSUâSTARS!,ããã»ããªã»ã¿ã from AIKATSUâSTARS!
- åºç社/ã¡ã¼ã«ã¼: ã©ã³ãã£ã¹
- çºå£²æ¥: 2015/10/28
- ã¡ãã£ã¢: CD
START DASH SENSATION ãã¸ç¥æ²ã§ã¢ããã¼ã·ã§ã³ä¸ããæ²ãè´ãã¦ï¼ããã¦ã©ã¤ãã観ã¦!!