קורס React 2020 שיעור תרגול: גישה ישירה ל DOM


זהו נושא דיון מלווה לערך המקורי שב־https://www.tocode.co.il/bundles/react/lessons/22-ref-lab
import React , {useState, useRef} from 'react';

const Ref = () => {

    const [location,setLocation] = useState(useRef(null));

    const location2 = useRef(null);

    const location3 = useRef(null);

    const location4 = useRef(null);

    const styleDiv = {

        background:"grey",

        width:"100px",

        height:"100px",

        float:"left",

        margin:"0 10px",

        "font-size":"100px",

        "text-align":"center",

}

    

    const Div = {

        width:"",

        height:"200px",

    }

    function writeText(e,locationa){

        locationa.current.textContent = e;

        if(locationa !== location4)

            locationa.current.nextSibling.focus();

        else

            location.current.focus();

    }

    return (

    <div style={Div}>

      <div style={styleDiv} ref={location} tabIndex={1}  onKeyPress={e=>writeText(e.target.value,location)}></div>

      <div style={styleDiv} ref={location2}  tabIndex={1} onKeyPress ={e=>writeText(e.target.value,location2)}></div>

      <div style={styleDiv} ref={location3} tabIndex={1} onKeyPress ={e=>writeText(e.target.value,location3)}></div>

      <div style={styleDiv} ref={location4}  tabIndex={1} onKeyPress ={e=>writeText(e.target.value,location4)}></div>

    </div>

    );

  }

export default Ref;
לייק 1

אשמח אם תעזרו לי לשפר את הפתרון כאן ותגידו לי מה הבעיה במצב של קליטת תו

הי @sarel190

נראה התחלה טובה - בוא ניקח את זה עוד צעד קדימה:

  1. יש לך רעיון איך לשנות את הקוד כך שאפשר יהיה לקבוע מבחוץ (למשל באמצעות Property) כמה ריבועים יהיו?

  2. מה קורה כשלוחצים עם העכבר על אחת התיבות כדי לתת לה פוקוס? יש לך רעיון איך לעדכן את משתנה ה State שלך (המשתנה location) כך שיישאר מעודכן גם אחרי לחיצה של משתמש על תיבה?

  3. לא נהוג לשמור את התוצאה של useRef ב State. עדיף לשמור שם דברים פשוטים כמו מספר.

זה בטעות ה useRef עם useState
אני שואל לגבי ה 4 useRef שיצרתי ברור לי שזה לא כתיבה נכונה אני מחפש משו לשיפור
לגבי הקטע עם העכבר זה עובד הוא מדלג כל פעם להבא בתור …

מה אם תשמור את כל התוצאות של useRef במערך?

ניסיתי וזה לא עבד לי משום מה
const location = useRef([null,null,null,null]);
התכוונת ככה נכון?

זה לא יעבוד. הפקודה useRef צריכה לקבל את הערך הראשוני של המשתנה ותמיד יוצרת משתנה אחד, אבל אתה צריך 4 משתנים. רעיונות נוספים?

אין תעזור לי כאן קצת

יש תשובה משו כאן???

יש לך 4 משתנים: location, location2, location3 ו location4, והם מתאימים ל-4 תיבות.

במצב כזה בדרך כלל אפשר להשתמש במערך שיחזיק את ארבעת הערכים. אחרי שתיצור כזה מערך תוכל לשמור מספר בודד שיהיה האינדקס של התיבה הפעילה, ולקדם רק אותו.

יש מצב לדוגמא לקוד כזה?
אפילו בפרטי

יש בעיה קטנה עם העיצוב (בכתיבה ראשונה לתיבות, משתנה המיקום. בטח בעיית CSS).
בנוסף, אני לא מצליח לדאוג לפוקוס בעליית הדף.

כן מוכר :slight_smile: זה נקרא vertical-align וצריך לתת שם את הערך top.

בנוגע לשאלה אחד - הכל עובד לי מצוין חוץ מבלחיצה על טאב ופוקוס בעת עליית הדף (חוץ מיוזאפקט).
כיצד אני יכולה לעשות זאת?

הי tp1

יש ב HTML מאפיין בשם autofocus שיכול לתת פיתרון פשוט בלי useEffect, יש עליו דיון כאן:

ובכל מקרה תמיד אפשר להשתמש גם ב useEffect לא חושב שיש משהו רע איתו

תודה.
פשוט יוזאפקט נמצא רק בהמשך הקורס אז ענין אותי אם יש דרך אחרת.
ומה בנוגע לטאב?

יש מאפיין בשם tabindex:

(בריאקט כותבים tabIndex עם I גדולה)

שצריך לפתור את זה. אם את מסתבכת יכולה להדביק קודפן לפיתרון שלך ואסתכל

מצרפת את התרגיל הראשון אשמח להערות,
לא הבנתי כיצד ניתן להשתמש בפונקציה componentDidUpdate בכתיב הפונקציות אז עשיתי עם useEffect. אשמח אם תוכל להסביר לי.


export default function InputFocusSwitch({count}) {
    const [rectanglesInnerText , setRectanglesInnerText] = useState({});
    const [currentFocusIndex , setCurrentFocusIndex] = useState(0);
    const refDivs = useRef(null);
    const style = {width: "25vw", height: "50vh", border:"1px solid blue", background: "lightblue",};

    function focus() { 
        refDivs.current.children[currentFocusIndex].focus(); 
    }
    useEffect(() => focus(),[]);
    useEffect(() => focus());

    function onKeyPressHandler(e , i) {
        rectanglesInnerText[i] = (rectanglesInnerText[i] || '') + e.key;
        setRectanglesInnerText({...rectanglesInnerText});
        setCurrentFocusIndex(i + 1 === count ? 0: i + 1);
    }

    return (
        <div style={{display:"flex"}} ref = {refDivs}>
            {
                (()=>{
                    const arr = [];
                    for (let i = 0 ; i < count ; i++) {
                        arr.push(
                            <div key={i} style = {style} tabIndex = {1} onKeyPress = {(e)=>onKeyPressHandler(e , i)}> {rectanglesInnerText[i]} </div>
                        )
                    }   
                    return arr;
                })()
            }
        </div>
    );
}