זהו נושא דיון מלווה לערך המקורי שב־https://www.tocode.co.il/bundles/react/lessons/state-prop
שלום, יש לי 2 שאלות אשמח אם תוכל בבקשה לענות לי.
1.) לגבי ה-()useState, לא ממש הבנתי איך הוא עובד.
כאשר מפעילים את הפונקציה שבאה מ-useState, מתוך פקד שמכיל בתוכו פקדים אחרים - ה-App למשל שמכיל Counters.
האם הוא לא מאתחל שוב מחדש את הפקדים שבתוכו ובעצם נוצרים פקדים חדשים?
אם כן , כיצד הפרמטר count שבתוך ה-Counter לא מאותחל מחדש ומתחיל מ-0?
2.) לגבי העברת מידע מהפקד הפנימי להוא שמעליו , רצית לדעת האם הרעיון שלי נכון:
אני העברתי הפונקציה שמגיעה מה-useState כ-property ל-Counter ושם בתוך הפונקציה inc אני מפעילה אותו בתנאי מסויים.
הי,
לא הבנתי את השאלה הראשונה. הפרמטר count אכן מאותחל מחדש אבל הערך שלו נלקח מהפעלה של פונקציית useState. בפעם הראשונה שמפעילים את הפונקציה היא מחזירה את הפרמטר שהיא קיבלה בסוגריים, אבל בפעם השניה שהיא תופעל היא תחזיר כבר את הערך הקודם שהיה שמור בסטייט.
אם ההסבר הזה עדיין לא ברור בבקשה תוסיפי דוגמת קוד או קצת יותר פרטים שאבין מה בדיוק לא ברור ואנסה לחדד.
- מדויק. בדרך כלל עושים משהו קצת יותר ספציפי: יוצרים פונקציה בפקד הראשי שעושה בדיוק את העדכון שאת רוצה, ואת הפונקציה הזאת מעבירים. בקוד זה נראה בערך כך:
function App() {
const [counter, setCounter] = useState(0);
function inc() { setCounter(c => c + 1); }
return (
<ChildComponent onClick={inc} />
<ChildComponent onClick={inc} />
);
}
אנחנו לא רוצים להעביר את setCounter עצמה כפרמטר לילדים כי אנחנו יודעים שלילדים האלה מותר להפעיל אותה רק בצורה מסוימת (רק להעלות ב-1 לדוגמה), ולא רוצים לתת להם ממשק יותר גנרי ממה שצריך
תודה!
לגבי השאלה הראשונה, לדוגמא בקוד הבא:
main.js
import React from 'react';
import ReactDOM from 'react-dom';
import { useState } from 'react';
import Counter from './counter';
const App = () => {
const [delta, setDelta] = useState(1);
function handleChangeDelta(e) {
const newValue = Number(e.target.value);
setDelta(newValue);
}
return (
<div>
<label>
Increase By:
<input type="number" value={delta} onChange={handleChangeDelta} />
</label>
<Counter delta={delta} />
</div>
)
};
const root = document.querySelector('main');
ReactDOM.render(<App />, root);
counter.js
import React from 'react';
import { useState } from 'react';
export default function Counter(props) {
const { delta } = props;
const [count, setCount] = useState(0);
function inc() {
setCount(x => x + delta);
}
return (
<div>
<p>
I was clicked {count} times
<button onClick={inc}>Click Me</button>
</p>
</div>
);
}
אני חשבתי שכאשר מופעלת הפונקציה - handleChangeDelta שמשנה את ה-state, וריאקט מפעילה שוב את הפונקציה App, אז הפקד - Counter שבתוכו נוצר ממש כמו פקד חדש. ואם הוא פקד חדש אז זו בעצם הפעם הראשונה שמופעלת הפונקציה שלו ואין לו עוד useState בזכרון.
ממך עכשיו אני מבינה שזה לא כך ולא ממש נוצר פקד חדש אלא הוא רק מעדכן את הפקד הישן.
אשמח אם תוכל יותר לחדד כיצד עובד ה - useState מאחורי הקלעים, ואיך הוא יודע האם הפקד הזה נוצר עכשיו או שכבר היה קיים.
תודה רבה!!!
נכון מאוד זה אותו פקד הוא פשוט מפעיל את הפונקציה מחדש אבל משתמש באותו State שכבר היה לו (וגם באותם אלמנטים שכבר היו על המסך). התוצאה של הפונקציה תייצר דבר שנקרא virtual dom חדש, אותו ריאקט ישווה למה שהוא כבר רואה על המסך כרגע וישנה את מה שמופיע על המסך כדי שיתאים למה שהפונקציה החזירה.
בשביל ליצור פקד חדש אנחנו צריכים שיהיה key חדש לדבר (ואני מדבר על זה בהמשך הקורס בשיעור על keys), או שהדבר מופיע במקום שונה ממה שהופיע בסיבוב הקודם
איך פותרים את השאלה שבסוף השיעור לא הצלחתי
הי אני רואה שהייתי ברור בוידאו - “לא הגעתם לתשובה, לא נורא, לא לוקחים ללב כי נדבר על זה בשיעורים הבאים”. אל דאגה עד סוף הקורס זה כבר יהיה ברור לגמרי (ואם לא תכתוב לי פה שוב ונדבר על זה)
- כשאני מקבלת props לקומפוננטה,
לפי מה שראיתי השם של המשתנה שאני מגדירה צריך להיות כמו השם של המשתנה ששלחתי מקומפוננטת האב.
לדוגמא:
בApp
<Button d = {delta}></Button>
בButton
function Button(props)
{
const d = props
....
למה זה?
- למה את המשתנה של הuseState צריך להגדיר עם סוגריים מרובעות : const [delta, setDelta] = useState(0);
ברחה לי השורה של הקוד בApp:
הי,
את המשתנה של ה useState נהוג להגדיר עם סוגריים מרובעות כי הפונקציה useState מחזירה מערך של שני דברים. הגדרת המשתנה עם סוגריים מרובעות בעצם מגדירה שני משתנים - אחד מקבל את האיבר הראשון מהמערך והשני את האיבר השני.
זה דומה לכתיב הזה:
const [a, b] = [2, 3]
רק במקרה של useState
הפונקציה useState מחזירה את המערך שנמצא מימין לסימן השווה.
לגבי ה props המשתנים שמעבירים מקומפוננטת האב נשמרים בתור מפתחות באוביקט props, כלומר אם אני מעביר:
<Button text="hello" />
אז בקומפוננטה Button יהיה לי אוביקט props ובו מפתח בשם text
והערך שלו יהיה המילה hello
, ואז בקוד של Button אפשר לכתוב:
function Button({text}) {
return <button>click: {text}</button>
}
או להשתמש ב Restructuring בתוך הפונקציה באופן הבא:
function Button(props) {
const {text} = props;
return <button>click: {text}</button>
}
אבל כמובן שזה רק דרך נוחה אבל לא מחייבת. אין בעיה ליצור משתנה בשם אחר:
function Button(props) {
const myText = props.text;
return <button>click: {myText}</button>
}
ואפילו להשתמש בכתיב ה Destructure כדי להגדיר את המשתנה החדש:
function Button({text: myText}) {
return <button>click: {myText}</button>
}