זהו נושא דיון מלווה לערך המקורי שב־https://www.tocode.co.il/bundles/react/lessons/e052aee2-e771-49c4-a76b-3ba1ae4f5970
זהו נושא דיון מלווה לערך המקורי שב־https://www.tocode.co.il/bundles/react/lessons/e052aee2-e771-49c4-a76b-3ba1ae4f5970
שלום @ynonp
אני מנסה ע"ב ההוקים useState useEffect ליצור תפריט צד הכולל את האפשרויות הבאות
תפריט רחב (טקסט ואייקון)
תפריט צר (אייקון בלבד)
המעבר ביניהם הוא ע"י לחיצה על אלמנט (כפתור)
עד כאן הכל בסדר
אני מעוניין להוסיף מצב בו העכבר מושהה לשנייה על התפריט הצר וע"י זה יתרחב התפריט עד לירידת העכבר ממנו.
וכאן שאלתי, האם זו הדרך?
export default function (props) {
const {setMenuOpen, isMenuOpen} = props;
const [isHover, setHover] = useState(false);
const [timeHover, setTimeHover] = useState(false);
const menuStyle = {
width: (isMenuOpen || isHover) ? '190px' : '50px',
}
const onHover = () => {
setTimeHover(true);
}
const onOut = () => {
setTimeHover(false);
setHover(false);
}
useEffect(()=>{
const timer = setTimeout(()=>{
if(timeHover){
setHover(true);
}
},1000);
return function abort(){
clearTimeout(timer);
}
}, [timeHover]);
return(
<aside className="side-menu" style={menuStyle} onMouseOver={onHover} onClick={()=>setHover(true)} onMouseOut={onOut}>
{menuItems.map((item)=>(
<ItemSideMenu item={item} menuOpen={isMenuOpen || isHover}/>
))
}
<button onClick={setMenuOpen} style={(isMenuOpen) ? {} : {transform : 'rotate(180deg)'}}></button>
</aside>
)}
השתמשתי בשלושה states לביצוע המשימה האם זו הדרך (נראה מסבוך בעליל) או שיש דרך קלה יותר?
הי,
מקריאה בגדול נראה שהכיוון טוב. אני חושד שאפשר לוותר על אחד המשתנים (isHover או timeHover) כי נראה שהם עושים עבודה דומה.
למה?
המשתנה timeHover מחזיק את העובדה שהסמן של העכבר על התפריט (ברגע שהסמן ירד המשתנה יקבל false)
ואילו המשתנה isHover מקבל true כאשר המשתנה timeHover היה true למשך שניה ברצף.
משהו מיותר?
היי ינון!
אני רוצה לתרגל פה חלק מהדברים שלומדים בקורס ובשביל זה אני מנסה לפתוח פרויקט חדש בריאקט עד עכשיו פתחתי רגיל לא עשה לי אף בעיות עשיתי בדרך הבאה: יצרתי תיקיה חדשה., עשיתי גיט באש היר וכתבתי: npx create-react-app . גם בטרמינל ב VSCODE ניסיתי וזה מביא לי את אותה שיגאה לא נותן לי ליצור פרויקט חדש
אולי תוכל לעזור לי בענין אני אשמח מאוד תודה רבה!*
הי יש שם איזה רווח מיותר בין המילה Users ל Desktop לא? (בשורת הפקודה שרשמת)
היי!
זה הענין אני לא כתבתי את הניתוב לתיקיה שבה אני רוצה ליצור את הפרויקט פשוט יצרתי תיקיה בשולחן עבודה ועשיתי
git bush here לא שיניתי מיקום או משהו לא יודעת למה הרווח הזה מופיע שם??
אני רואה שיש שם גם קישור לקובץ log שהוא טוען שכל המידע כתוב בו - אולי את יכולה להסתכל שם (או להדביק לכאן את הקובץ) נראה אם יש בו משהו חשוד?
בקשר לשאלה 2 , אני רוצה לוודא שהבנתי.
אם הייתי מעבירה ערך קבוע ticks + 1. הפונקציה tick שמועברת ל-setInterval תתייחס תמיד לאותו ticks שהיה בעת ההגדרה וכך תשאר תקועה תמיד ב-1.
מכיון שה-useEffect קורה פה רק פעם אחת בעת עלית הפקד אז הוא לא מעדכן את הפונקציה שבתוכו להצביע על הפונקציה של הרנדר הנוכחי?
לכן אם היינו משתמשים פה ב-setTimeout שהיה נקרא בכל שינוי של ticks, לא היתה בעיה עם הכתיב הזה:
function Timer(props) {
const [ticks, setTicks] = useState(0);
function tick() {
setTicks(ticks + 1);
console.log('Ouch!');
}
useEffect(function() {
const timer = setTimeout(tick, 1000);
return function cancel() {
clearInterval(timer);
}
}, [ticks]);
return (
<p>Ticks: {ticks}</p>
);
}
אם כן, האם זה לא בזבזני שבכל רנדר מוגדרת פונקציה חדשה שבעצם לא משתמשים בה.
(אני מתכוונת לדוגמא פה בטאב טקסט, בוידאיו לא העברת אותה אלא כתבת אותה בתור פונקציה אנונימית)
הי הי,
יש פה שני שינויים בדוגמה שלך וחשוב לשים לב לאפקט של שניהם:
-
את משתמשת ב setTimeout במקום ב setInterval
-
את מגדירה במערך התלויות של האפקט את המשתנה ticks
השינוי השני הוא המשמעותי יותר, כי הוא גורם לזה שהאפקט יופעל כל פעם מחדש אחרי כל שינוי ב ticks, במקום פעם אחת בלבד בכניסה של הפקד למסך (כמו שהיה בקוד הדוגמה שלי).
אבל כן את מתארת יפה את הבעיה ואלה דברים קטנים שטוב לשים לב אליהם. באותו הקשר מומלץ מאוד לקרוא את הפוסט המאוד מפורט הזה של דן אברמוב על הנושא: