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

למאמר הקודם בסדרה על ריאקט
למאמר הבא בסדרה על ריאקט

במאמר הקודם למדנו על ׳מעגל החיים׳ של קומפוננטות ריאקט. לא, זה לא שיר גרוע של אלטון ג׳ון מסרט מפוקפק משהו אלא אוסף של מתודות שנקראות לאורך החיים של הקומפוננטה. במאמר הזה אנו נלמד על חיבור של קומפוננטה ריאקטית לאלמנטים ב-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, זה הזמן לעבור על המדריכים שיש עליו פה באתר כדי להבין מה הוא ואיך עובדים איתו.

אהבתם? לא אהבתם? דרגו!

לא אהבתי בכלללא אהבתיבסדראהבתיאהבתי מאוד (8 הצבעות, ממוצע: 4.75 מתוך 5)

תגיות: פורסם בקטגוריה: ריאקט

יאללה, שתפו :)

אל תשארו מאחור! יש עוד מה ללמוד!

כתיבת תגובה

האימייל לא יוצג באתר.

רישום