חיבור של DOM לקומפוננטות ריאקטיות

הסבר על ref ואיך עובדים איתם בריאקט

במאמר הקודם למדנו על ׳מעגל החיים׳ של קומפוננטות ריאקט. לא, זה לא שיר גרוע של אלטון ג׳ון מסרט מפוקפק משהו אלא אוסף של מתודות שנקראות לאורך החיים של הקומפוננטה. במאמר הזה אנו נלמד על חיבור של קומפוננטה ריאקטית לאלמנטים ב-DOM. כלומר אלמנטים טבעיים (כמו למשל input). למה צריך את זה בעלל? למה אנחנו צריכים אלמנטים טבעיים? התשובה היא שבסופו של דבר, בבסיס כל הקומפוננטות יש אלמנטי UI אמיתיים שצריך להתחבר אליהם ולעבוד איתם.

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


class NameDisplay extends React.Component {
  constructor(props, context) {
    super(props, context);
    this.state = {
      name: ''
    };
    this.nameValue = this.nameValue.bind(this);
  }
  nameValue(e) {
    this.setState({ name: e.target.value });
  }
  
  render() {
    const bigStyle = {
      backgroundColor: 'yellow',
      borderRadius: 10,
      color: 'silver',
      fontSize: '42px',
      minHeight: '30px',
      textAlign: 'center',
      width: '250px',
    };
    return <div style={bigStyle}>
        {this.state.name}
       <form>
         <input onChange={this.nameValue} placeholder="Enter your name"></input>
       </form>
      </div>
  }
}

const target = document.getElementById('content');
ReactDOM.render(
  <NameDisplay />,
  target
);

בואו רק נעבור עליו ליתר בטחון ולהבנה. יש לי כאן input שיש לו אירוע onChange. כשאני מקליד בתוכו משהו, ה-onChange קורא ל-nameValue שלוקח את מה שיש באלמנט ה-input ומכניס אותו ל this.state.name שמוצג ב-JSX. כך כל מה שאני מכניס לתיבת הטקסט מופיע. לא נשכח להכניס

    this.nameValue = this.nameValue.bind(this);

לקונסטרקטור כדי שלפונקצית nameValue תהיה גישה ל this שלנו למרות שהיא מופעלת מה-onChange.

See the Pen React component with ref phase 1 by Ran Bar-Zik (@barzik) on CodePen.

טוב, הכל טוב ויפה. אבל אז מגיע אלינו מנהל הפרויקט הנתעב ואומר לנו שזה לא טוב לו. למה? הוא לא רוצה שהשם יופיע כשמקלידים. הוא רוצה שרק כאשר המשתמש ילחץ על כפתור submit אז הערך יוצג. למה? כי ״זה לא נראה טוב כשמקלידים חצי שם והלקוח יתבלבל״. אחרי שנכה את אותו מנהל עם עיתון מגולגל, נצטרך לעשות כדבריו. אבל זה די פשוט. התצוגה תהיה של משתנה state אחר (למשל displayName) ונוסיף כפתור submit שלחיצה עליו תגרום לערך הזה להכנס אל nameValue המוצג.


class NameDisplay extends React.Component {
  constructor(props, context) {
    super(props, context);
    this.state = {
      name: '',
      displayName: ''
    };
    this.nameValue = this.nameValue.bind(this);
    this.setdisplayName = this.setdisplayName.bind(this);
  }
  nameValue(e) {
    this.setState({ name: e.target.value });
  }
  setdisplayName() {
    this.setState({ displayName: this.state.name });
  }
  
  render() {
    const bigStyle = {
      backgroundColor: 'yellow',
      borderRadius: 10,
      color: 'silver',
      fontSize: '42px',
      minHeight: '30px',
      textAlign: 'center',
      width: '250px',
    };
    return <div style={bigStyle}>
        {this.state.displayName}
       <form>
         <input onChange={this.nameValue} placeholder="Enter your name"></input>
         <button type="button" onClick={this.setdisplayName}>Submit</button>
       </form>
      </div>
  }
}

const target = document.getElementById('content');
ReactDOM.render(
  <NameDisplay />,
  target
);

הנה מה שעשיתי, לפי הצעדים:

1. יצירת nameValue ב-state.
2. יצירת setDisplayName שלוקחת את ה-this.state.name ומכניסה אותו ל-displayName.
3. לא שוכח לעשות bind ב-constructor ל-setDisplayName.
4. יוצר כפתור פשוט עם type=button ובכל לחיצה עליו מפעיל את setDisplayName.

See the Pen React component with ref phase 2 by Ran Bar-Zik (@barzik) on CodePen.

ועכשיו לפואנטה. מנהל הפרויקט מגיע אליכם שוב ואומר שהוא רוצה שה-input יתנקה לאחר ה-submit. אחרי שאתם מצליפים בו בשוט הרכיבה שלכם (עיתון מגולגל לא יספיק הפעם) – נשאלת השאלה איך עושים את זה? בדיוק בשביל זה אני צריך יכולת לתקשר עם רכיב ה-input בדרך כזו שתאפשר לי להפעיל אותו. את זה אני עושה באמצעות ref – זו פשוט תכונה ב-JSX שמאפשרת לי לשייך את האלמנט שלי למשתנה ב-class שאליו אני יכול לגשת בקלות. עושים את זה כך:

ref={(el) => { this._input = el; }}

ואז אני יכול להשתמש ב this._input בכיף בקוד שלי. במקרה הזה, אוכל לנקות אותו ולעשות עליו פוקוס. כן, זה עד כדי כף פשוט. שימו לב לקוד ולדוגמה החיה:

class NameDisplay extends React.Component {
  constructor(props, context) {
    super(props, context);
    this.state = {
      name: '',
      displayName: ''
    };
    this.nameValue = this.nameValue.bind(this);
    this.setDisplayName = this.setDisplayName.bind(this);
  }
  nameValue(e) {
    this.setState({ name: e.target.value });
  }
  setDisplayName() {
    this.setState({ displayName: this.state.name });
    this._input.focus();
    this._input.value = '';
  }
  
  render() {
    const bigStyle = {
      backgroundColor: 'yellow',
      borderRadius: 10,
      color: 'silver',
      fontSize: '42px',
      minHeight: '30px',
      textAlign: 'center',
      width: '250px',
    };
    return <div style={bigStyle}>
        {this.state.displayName}
       <form>
         <input onChange={this.nameValue} ref={(el) => { this._input = el; }} placeholder="Enter your name"></input>
         <button type="button" onClick={this.setDisplayName}>Submit</button>
       </form>
      </div>
  }
}

const target = document.getElementById('content');
ReactDOM.render(
  <NameDisplay />,
  target
);

See the Pen React component with ref phase 3 by Ran Bar-Zik (@barzik) on CodePen.

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

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

⚠️אם אהבת את המדריכים על ריאקט – יש ספר מקיף ושלם על ריאקט שכתבתי בשם ללמוד ריאקט בעברית, במסגרת פרויקט עם חברות מובילות ומפתחים אחרים. בספר יש פירוט מקיף יותר על ריאקט ותרגילים רבים ללימוד עצמי. 

פוסטים נוספים שכדאי לקרוא

DALL·E 2024-09-06 12.34.24 - A visually engaging post about Python and cryptographic problems. The image should feature a dark-themed background with a glowing, futuristic Python
פתרונות ומאמרים על פיתוח אינטרנט

בעיות במימוש של פונקציות קריפטוגרפיות בפייתון

היום (16 לספטמבר) ממש, אני מעביר הרצאה ב-PyconIL 2024 על בעיות קריפטוגרפיות באפליקציות פייתון. לצערי אי אפשר להכניס את כל הבעיות הקריפטוגרפיות להרצאה אחת או

מיקרו בקרים

חיבור מצלמה למיקרובקר

חיבור מצלמה למיקרו בקר ויצירה של מצלמת אבטחה מרחוק בעלות של 20 שקל.

רספברי פיי

מה זה AIoT? ואיך אפשר להתחיל?

פוסט עם המון קישורים, מידע, סרטונים ופרק בפודקאסט שיפתח לכם שער לעולם ה-AIoT המרתק.

גלילה לראש העמוד