ToCode
Ir al canal en Telegram
1 419
Suscriptores
-124 horas
Sin datos7 días
-230 días
Archivo de publicaciones
1 419
# טיפ JavaScript: עדכון פרמטרים של שורת כתובת
כתובת אינטרנט יכולה להכיל פרמטרים אחרי סימן שאלה שמגיעים בפורמט של שם הפרמטר ואז סימן שווה ואז הערך שלו - למשל בכתובת הבאה יש שני פרמטרים בשמות foo ו bar עם הערכים 10 ו 20:
http://www.tocode.co.il?foo=10&bar=20
אם אתם עדיין משתמשים בביטויים רגולאריים או פונקציות לעריכת טקסט כדי לקבל ולעדכן את הערכים של אותם פרמטרים, תשמחו לשמוע שמזמן יש פיתרון חדש שעובד ברוב הדפדפנים ונקרא URLSearchParams. בשביל להשתמש בו אני יוצר אוביקט URL מהכתובת, ואז קורא לפונקציה searchParams של אותו אוביקט. כשיש לי ביד searchParams אני יכול להפעיל את הפונקציות שלו כדי לקרוא ולעדכן את משתני החיפוש. הפונקציות המעניינות הן:
1. פונקציית get שמקבלת שם של פרמטר ומחזירה את הערך הראשון שמקושר אליו
2. פונקציית append שמוסיפה ערך חדש לפרמטר (יכולים להיות כמה מופעים של אותו פרמטר, אז שימו לב לקרוא לה כמה פעמים רק אם אתם באמת צריכים - למשל בשביל לייצג מערך).
3. פונקציית set שמעדכנת ערך של פרמטר ומשאירה רק מופע אחד שלו.
את שאר הפונקציות אפשר למצוא בתיעוד כאן:
https://developer.mozilla.org/en-US/docs/Web/API/URLSearchParams
בעזרת אותן פונקציות אני יכול לשלוף ולהדפיס את הערכים של foo ו bar מהכתובת הקודמת:
const url = new URL("http://www.tocode.co.il?foo=10&bar=20");
> url.searchParams.get('foo')
'10'
> url.searchParams.get('bar')
'20'
או לעדכן את אחד הערכים, להוסיף פרמטר חדש ולקבל את הכתובת המעודכנת:
> url.searchParams.set('foo', 'new value')
> url.searchParams.set('newKey', 12)
> url.toString()
'http://www.tocode.co.il/?foo=new+value&bar=20&newKey=12'1 419
# הדרך השניה
כשלומדים טכנולוגיה חדשה בפעם הראשונה הנטיה הטבעית היא לחפש "איך עושים דברים". ברגע הזה לא מעניין אותי לדעת שיש 3 דרכים להגדיר פונקציה או 5 דרכים להגדיר משתנה. הדרך השניה רק תבלבל אותי יותר, כי עוד לא הבנתי את הדרך הראשונה.
הבעיה מתחילה כשאחרי שלמדנו את הדרך הראשונה אנחנו עוצרים וחושבים שזו הדרך הכי "פשוטה", הכי "טובה", הכי "אינטואיטיבית" או הכי "מהירה" לעשות דברים. שאם מכל הדרכים שהיו זמינות לי יצא שלמדתי את הדרך המסוימת הזאת, בטח היתה לי סיבה טובה ובטח כדאי להמשיך להשתמש בה.
ואז אנחנו מתחילים להצדיק אחורה בחירות טכנולוגיות, למשל "אצלנו כותבים את המוצר בפריימוורק X כי הוא הכי קל ללמידה", או "אנחנו לא משתמשים בכלי Y כי זה רק יאט אותנו", וגם "נכון שכולם טוענים ששיטה Z נותנת ביצועים יותר טובים, אבל בשביל המוצר שלנו שיטה X מספיק טובה". בלב אולי הייתם שמחים להכיר גם את הדרכים האחרות, אבל כרגע בהתחשב במוצר, בתקלות, בסדרי העדיפויות ושאר האילוצים של העולם, מה עכשיו ללמוד עוד דרך לעשות בדיוק את אותו דבר? לא חבל על הזמן?
אולי. אבל יש עוד אפשרויות-
אולי זה לא ייקח כל כך הרבה זמן, כי אחרי שמכירים דרך אחת יותר קל ללמוד דרכים נוספות?
אולי הדרך השניה באמת יותר טובה?
אולי היכרות עם עוד דרך תעזור לך להבין טוב יותר את הקוד של הדרך הראשונה?
אולי באותו רגע של התחלה באמת הדרך הראשונה היתה טובה יותר עבורך, אבל זה לא אומר שהיא תישאר כזאת לתמיד. בדיוק כרגע, בהתחשב במוצר, בתקלות ובסדרי העדיפויות, הדרך השניה היא הדרך קדימה.
1 419
טעות דומה למרות שפחות מטרידה אפשר לראות בקוד הבא:
function TitleEditor() {
const [title, setTitle] = useState(document.title);
useEffect(() => {
document.title = title;
}, [title]);
function handleChange(e) {
setTitle(e.target.value);
}
return (
<input type="text" value={title} onChange={handleChange} />
);
}
זו קומפוננטה שמציגה תיבת טקסט, וכל שינוי של הטקסט בתיבה גם מעדכן את ה title של העמוד. הקוד עובד אבל השימוש באפקט כאן צורם: אין פה באמת סינכרון בין משהו חיצוני למשתנה ריאקט, אין פונקציית ניקוי לאפקט ונכון שלא יקרה נזק אם נריץ את האפקט כמה פעמים אבל בתכל'ס כל הרצה נוספת של האפקט כשה title כבר מתאים למשתנה הסטייט היא פשוט מיותרת.
במקום זה אפשר לוותר על האפקט ולכתוב את הקומפוננטה בצורה הבאה והיותר יעילה:
function TitleEditor() {
const [title, setTitle] = useState(document.title);
function handleChange(e) {
setTitle(e.target.value);
document.title = e.target.value;
}
return (
<input type="text" value={title} onChange={handleChange} />
);
}
מקווה שהפוסט הזה יעזור לכם לטעות פחות עם useEffect ולחשוב עליו כמו שהוא - מנגנון סינכרון בין קוד ריאקט למצב עניינים חיצוני שקורה בדפדפן. וכמובן אם נתקלתם בטעויות נוספות בעבודה עם useEffect שלא חשבתי עליהן כאן, אשמח לשמוע בתגובות.1 419
}}
>
Click me!
</button>
</div>
)
(ותודה לניקולה מרגיט על הדוגמה הזאת).
חוסר תיאום בין פונקציית האפקט למערך התלויות הוא תקלה כל כך נפוצה שיש פלאגין ל eslint שמזהה אותה ומומלץ מאוד להשתמש בו בפרויקט שלכם:
https://www.npmjs.com/package/eslint-plugin-react-hooks.
## להשתמש באוביקט מקונן במערך התלויות
באג עדין נוסף ומאוד נפוץ עם מערך התלויות קורה כשאני משתמש באוביקט מקונן בתוך מערך זה. הבעיה כאן היא ששינוי בשדה פנימי של אוביקט לא גורם לריענון האפקט, ולכן נדמה לנו שהאפקט מסונכרן כשבעצם הוא לא. הנה דוגמה פשוטה שצובעת את הרקע של הפיסקה באדום רק פעם אחת ולא מרעננת את הצבע אם הפיסקה מצוירת מחדש:
function BadRef() {
const ref = useRef(null);
const [visible, setVisible] = useState(true);
useEffect(() => {
if (ref.current) {
ref.current.style.backgroundColor = 'red';
}
}, [ref]);
return (
<div>
<input type="checkbox" checked={visible} onChange={(e) => setVisible(e.target.checked)} />
{visible && <p ref={ref}>just some text</p>}
</div>
);
}
והתיקון הוא פשוט:
function BadRef() {
const ref = useRef(null);
const [visible, setVisible] = useState(true);
useEffect(() => {
if (ref.current) {
ref.current.style.backgroundColor = 'red';
}
}, [ref.current]);
return (
<div>
<input type="checkbox" checked={visible} onChange={(e) => setVisible(e.target.checked)} />
{visible && <p ref={ref}>just some text</p>}
</div>
);
}
## לשכוח להחזיר פונקציית ניקוי
טעות שלישית ברשימה היא לכתוב אפקט בלי פונקציית ניקוי. עד ריאקט 18 זה לא היה ממש טעות כי לפעמים לפי מערך התלויות היה אפשר לדעת מתי האפקט ירוץ, אבל החל מריאקט 18 אנחנו צריכים לחשוב על אפקטים בתור משהו שאפשר תמיד להסיר ולהוסיף אותו מחדש, ואסור לנו להניח שאפקט ירוץ רק פעם אחת. במצב פיתוח ריאקט אפילו מבלבל אותנו ובכוונה מריץ את כל האפקטים פעמיים כדי לוודא שהקוד שלנו לא מסתבך עם זה.
לכן קומפוננטה כזאת כבר אסור לכתוב בריאקט 18:
function WindowSize(props) {
const [width, setWidth] = useState(window.innerWidth);
const [height, setHeight] = useState(window.innerHeight);
const { updateMs=1000 } = props;
useEffect(() => {
const handleResize = _.debounce(function handleResize() {
setWidth(window.innerWidth);
setHeight(window.innerHeight);
}, updateMs);
window.addEventListener('resize', handleResize);
}, []);
return (
<p>Window Size: {width}x{height}</p>
);
}
אפילו שמערך התלויות ריק, עדיין לא מובטח לנו שהאפקט ירוץ רק פעם אחת.
## לשכוח מתי אפקט רץ
ברגע שיש שינוי באוביקט במערך התלויות, השינוי הזה גורם לריאקט לרנדר מחדש את הקומפוננטה ורק אחרי הרינדור מחדש והפעלה נוספת של useEffect ריאקט מזהה שצריך להריץ מחדש את האפקט. לכן אפקט ירוץ תמיד אחרי הרינדור של הערך שגרם לו.
נתבונן בדוגמה הבאה:
function EvenOdd() {
const [count, setCount] = useState(0);
const [isEven, setIsEven] = useState(true);
useEffect(() => {
setIsEven(count % 2 === 0);
}, [count]);
return (
<div>
<p>{isEven ? "Even" : "Odd"}</p>
<button onClick={() => setCount(c => c + 1)}>Clicks: {count}</button>
</div>
);
}
הקומפוננטה עובדת ומציגה מונה לחיצות ומעליו הטקסט - כשהמספר זוגי מופיעה המילה Even וכשאי זוגי מופיעה המילה Odd.
הבעיה כאן היא שכל לחיצה על הכפתור יוצרת מספר כפול של render-ים. במקום לעדכן את הערך של count ולרנדר את הקומפוננטה מחדש כדי להציג את הערך המעודכן, אנחנו מעדכנים קודם כל את count, מציגים אותו, ואז מעדכנים את isEven ושוב מרנדרים את הקומפוננטה.
נשים לב גם שלאפקט הזה אין פונקציית ניקוי והוא לא "מסנכרן" משתני ריאקט עם משהו שנמצא בחוץ אלא הוא פשוט אמור לסנכרן בין שני משתני סטייט באותה קומפוננטה. במקרה הזה הרבה יותר יעיל היה להשתמש במשתנה סטייט יחיד. אפילו אם חייבים להשתמש בכמה משתני סטייט, עדיף לעדכן אותם יחד באותה פונקציה עם כמה קריאות ל setState ולא דרך אפקט.1 419
# ארבע טעויות נפוצות בשימוש ב useEffect
המעבר לעבודה בשיטת ה Hooks היה נשימה לרווחה עבור מתכנתי ריאקט רבים, ומקור ללחץ עבור אחרים. בכל מקרה מעבר זה דרש שינוי שיטת חשיבה והוביל לקוד ריאקט שנכתב אחרת. הפונקציה useEffect היתה כנראה ה Hook המסובך מכולם, מאחר והיא החליפה מספר פונקציות מחזור חיים שהגיעו לפניה ועדיין עבדה קצת אחרת מהשילוב של כולן. בפוסט זה אסקור 4 טעויות נפוצות בשימוש ב useEffect שאני מקווה שיעזרו לכם להשתמש בו נכון ולכתוב קומפוננטות ריאקט טובות יותר.
## לעדכן קוד ולשכוח לעדכן את מערך התלויות
טעות מספר אחת והנפוצה ביותר בעבודה עם useEffect באה לידי ביטוי בדרך כלל כשאנחנו מעדכנים קוד קיים, למרות שיכולה לקרות גם בכתיבת אפקט חדש. הרעיון הוא פשוט, בכל useEffect אנחנו צריכים להעביר בתור פרמטר שני מערך של "תלויות", כלומר דברים שכשהם משתנים יש ליצור מחדש את האפקט. הבעיה שכשמעדכנים קוד קיים הרבה פעמים אנחנו שוכחים לעדכן את מערך התלויות, מה שמייצר באגים שלפעמים קשה לאתר.
נתבונן בקומפוננטה הבאה שמציגה את גודל החלון, וגם מעדכנת את התצוגה כל פעם שהגודל משתנה:
function WindowSize() {
const [width, setWidth] = useState(window.innerWidth);
const [height, setHeight] = useState(window.innerHeight);
useEffect(() => {
const handleResize = _.debounce(function handleResize() {
setWidth(window.innerWidth);
setHeight(window.innerHeight);
}, 1000);
window.addEventListener('resize', handleResize);
return () => {
window.removeEventListener('resize', handleResize);
}
}, []);
return (
<p>Window Size: {width}x{height}</p>
);
}
הקומפוננטה משתמשת ב _.debounce כדי לעדכן את התצוגה לא יותר מפעם בשניה. עכשיו בואו נניח שמישהו בעתיד רוצה להפוך את הקוד הזה ליותר גנרי, ולקבל מבחוץ את הפרמטר ל debounce. הקוד המעודכן עם הבאג יהיה:
function WindowSize(props) {
const [width, setWidth] = useState(window.innerWidth);
const [height, setHeight] = useState(window.innerHeight);
const { updateMs=1000 } = props;
useEffect(() => {
const handleResize = _.debounce(function handleResize() {
setWidth(window.innerWidth);
setHeight(window.innerHeight);
}, updateMs);
window.addEventListener('resize', handleResize);
return () => {
window.removeEventListener('resize', handleResize);
}
}, []);
return (
<p>Window Size: {width}x{height}</p>
);
}
אם ניצור את הקומפוננטה ונעביר לה ב props את הערך של updateMs ואז נעביר ערך אחר במקום, האפקט לא יתעדכן ותמיד ישתמש בערך הראשון שעבר.
דוגמה נוספת וקצת יותר עדינה היא הקוד הזה:
function WrongCounter() {
const [clickCount, setClickCount] = React.useState(0)
React.useEffect(() => {
const timeout = setTimeout(() => {
alert(clickCount)
}, 5000)
return () => clearTimeout(timeout)
}, [])
return (
<div>
<h1>Hello!</h1>
<button onClick={() => setClickCount((prevCount) => prevCount + 1)}>
Click me!
</button>
</div>
)}
הפעם האפקט משתמש בערך של clickCount אבל אותו משתנה סטייט לא נמצא במערך התלויות. לכן אחרי שמעדכנים את הערך האפקט לא משתנה וה alert תמיד ידפיס 0.
בעוד שבדוגמה הראשונה כל מה שצריך בשביל לתקן את הקוד הוא לתקן את מערך התלויות. בדוגמה השניה הסיפור יותר עדין כי אם אני אוסיף את clickCount למערך התלויות ובאמת אצור מחדש את האפקט כל פעם שהוא ישתנה אז ההתנהגות של הקומפוננטה תשתנה - במקום להקפיץ את ה alert חמש שניות אחרי שהקומפוננטה נכנסה למסך, היא תוקפץ 5 שניות אחרי הלחיצה האחרונה על הכפתור. בשביל לשמור על ההתנהגות אני דווקא כן צריך את מערך התלויות ריק, אבל עליי לבטל את התלות ב clickCount. בשביל זה אני יכול לשמור את מספר הלחיצות במשתנה Ref:
const [clickCount, setClickCount] = React.useState(0)
const countRef = React.useRef()
React.useEffect(() => {
const timeout = setTimeout(() => {
alert(countRef.current)
}, 5000)
return () => clearTimeout(timeout)
}, [])
return (
<div>
<h1>Hello!</h1>
<button
onClick={() => {
countRef.current = clickCount + 1
setClickCount((prevCount) => prevCount + 1)1 419
# רעיונות שלא בטוח עובדים
אם הקשבתם יותר מדי בבית ספר אתם עלולים לחשוב שלרעיונות יש ערך רק אם הם עובדים. הציון שתקבלו במבחן נקבע לפי מספר התשובות הנכונות שכתבתם, ולא לפי מספר התשובות הכולל שעניתם לשאלה (ובכלל אני לא חושב שמישהו בבית ספר אי פעם ביקש ממני לענות כמה תשובות שונות לאותה שאלה). זה כאילו המטרה היחידה שם היתה להכיר את הרעיון שעובד.
הגיע הזמן שנתגבר על השקר הזה.
רעיונות שלא עובדים הם בעלי ערך, הרבה פעמים גדול בהרבה מרעיונות שעובדים. ברוב המקצועות היצירתיים היום, ובתכנות במיוחד, רעיונות שלא עובדים חייבים להיות חלק מרכזי מהחיים שלנו.
אם תבקשו ממני לכתוב תוכנית שמדפיסה על המסך Hello World בשפת תכנות שאני מכיר אני בטוח שאדע איך לעשות את זה. אותו דבר אם אנסה לכתוב משחק טטריס. אבל אם אצטרך לממש לקוח git מאפס זה כבר הולך להיות קשה. יש לי רעיון כללי איך להתחיל אבל אני לא יודע אם הוא יעבוד, ואני די בטוח שחלק מהדברים שאעשה לא יעבדו בפעם הראשונה. הסיבה היחידה שאני יכול לכתוב בקלות טטריס אבל לא בטוח איך לכתוב גיט היא שכבר כתבתי משחקי טטריס בכמה שפות, ואף פעם לא כתבתי לקוח גיט. הדרך קדימה לכתוב דברים שעוד לא כתבתי בעבר עוברת בהכרח דרך רעיונות שעוד לא ניסיתי, ושאולי לא יעבדו. אותם רעיונות שלא בטוח יעבדו הם המפתח להתקדמות.
יותר מזה, אם הדבר היחיד שאני עושה בעבודה הוא לכתוב רק דברים שאני מכיר, מהר מאוד העבודה תהיה מאוד משעממת. אף אחד לא רוצה להישאר עשר שנים במקום שבו כל בוקר כותבים מחדש טטריס. רעיונות שלא בטוח יעבדו מוסיפים עניין ואושר לחיים, וזה חלק מהדברים שאנחנו צריכים כבני אדם.
ובכל זאת רבים מאיתנו חוששים מרעיונות שלא בטוח יעבדו ולא בטוחים איך להגיע אליהם ולשלב אותם בחיי היום יום. הנה שלושה מפתחות שיעזרו לנו לשלב רעיונות כאלה בחיי היום יום:
## רעיונות שלא עובדים צריכים זמן
המפתח הראשון הוא המסגרת - המקום והזמן, שבו מותר לנסות דברים שלא בטוח יעבדו. אם תלמיד שואל אותי שאלה בקורס הוא מצפה לקבל תשובה אמינה. זאת לא סיטואציה שבה רצוי לנחש רעיון שלא בדקתי. אפילו בשאלות שאני לא יודע עדיף להגיד את זה בצורה ישירה, להגיד שאבדוק ולחזור עם תשובה שעובדת.
לעומת זאת אם אני יושב בבית ובונה לקוח גיט, אין שום בעיה שאני מנסה רעיון, הרעיון הזה לא מצליח. אפשר למחוק את כל הקוד ולהתחיל מחר שוב בכיוון אחר.
בשביל לשלב רעיונות שלא בטוח עובדים בחיים שלנו אנחנו רוצים לתת להם את המקום והזמן שבו הם יוכלו להרגיש בנוח, ואנחנו נוכל להרגיש איתם בנוח.
## רעיונות שלא עובדים לא אוהבים שמודדים אותם
המפתח השני הוא המטרה, או מה אני מנסה להשיג עם רעיונות שלא בטוח עובדים. אם הגישה שלי היא שזמן שמושקע בכתיבת קוד חייב "להחזיר את ההשקעה" אז יהיה לי קשה מאוד לבזבז 3 שעות על ניסיון לבנות לקוח גיט שלא יעבוד. סיכוי טוב שאני אפילו לא אתחיל כי איזה החזר השקעה בכלל אפשר לקבל מפרויקט כזה.
ובדיוק מהגישה הבית ספרית הזאת אנחנו רוצים להיפרד.
מימוש רעיונות שלא בטוח יעבדו בתוך המקום והזמן שמוקדש להם הוא המטרה. אני בונה את זה כדי לבנות את זה, ואם בסוף גם יצא פרויקט זה אחלה, אבל גם אם לא זה ממש בסדר.
הבלוג הזה הוא דוגמה למשחק שלי עם רעיונות שלא בטוח עובדים. אני כותב כל יום, חלק מהפוסטים מדברים לאנשים וחלק לא, וזה מעולה. אני לא מסתכל כמה אנשים נכנסים לקרוא פוסט או משתפים אותו כי זאת לא המטרה. הכתיבה היא המטרה של עצמה.
## אפשר (וכדאי) ליישם רעיונות שלא עובדים בכל תחום בחיים
תרגול עוזר, וגם שילוב רעיונות שלא בטוח עובדים בחיים שלנו זו מיומנות שדורשת תרגול. יכול להיות שבעבודה המקצועית שלכם אתם לא רואים עכשיו שום מקום שבו אפשר לנסות רעיונות שלא בטוח עובדים. יכול להיות שאתם מרגישים שמודדים כל צעד שלכם ושאתם בארגון שלא מאפשר לכם את החופש שאתם רוצים. יש הרבה מקומות כאלה.
הפיתרון הוא להתחיל מאזורים אחרים בחיים שאולי בהם יש לכם יותר חופש - עם המשפחה, בשעות הפנאי, בתחביבים. אם יש לכם ילדים קטנים תוכלו להחליט שפעם בשבוע תאספו את הילדים מהמסגרת לפעילות קצרה שעדיין לא ניסיתם איתם ושהם אולי לא יאהבו. או אם אתם אוהבים ספורט תוכלו להחליט שפעם בשבוע או שבועיים תנסו סוג אימון חדש שעוד לא ניסיתם ואולי לא תאהבו.
מה שיפה ברעיונות זה שככל שאנחנו נותנים להם את המקום והזמן, ככל שאנחנו לא מודדים אותם, וככל שאנחנו מנסים יותר מהם, כך יותר קל לחשוב על רעיונות חדשים. ולאט לאט מעגל הקסמים מתרחב ואנחנו מגלים את הכיף ביישום רעיונות שלא בטוח עובדים ביותר ויותר תחומים בחיים.
1 419
# רעיונות שלא בטוח עובדים
אם הקשבתם יותר מדי בבית ספר אתם עלולים לחשוב שלרעיונות יש ערך רק אם הם עובדים. הציון שתקבלו במבחן נקבע לפי מספר התשובות הנכונות שכתבתם, ולא לפי מספר התשובות הכולל שעניתם לשאלה (ובכלל אני לא חושב שמישהו בבית ספר אי פעם ביקש ממני לענות כמה תשובות שונות לאותה שאלה). זה כאילו המטרה היחידה שם היתה להכיר את הרעיון שעובד.
הגיע הזמן שנתגבר על השקר הזה.
רעיונות שלא עובדים הם בעלי ערך, הרבה פעמים גדול בהרבה מרעיונות שעובדים. ברוב המקצועות היצירתיים היום, ובתכנות במיוחד, רעיונות שלא עובדים חייבים להיות חלק מרכזי מהחיים שלנו.
אם תבקשו ממני לכתוב תוכנית שמדפיסה על המסך Hello World בשפת תכנות שאני מכיר אני בטוח שאדע איך לעשות את זה. אותו דבר אם אנסה לכתוב משחק טטריס. אבל אם אצטרך לממש לקוח git מאפס זה כבר הולך להיות קשה. יש לי רעיון כללי איך להתחיל אבל אני לא יודע אם הוא יעבוד, ואני די בטוח שחלק מהדברים שאעשה לא יעבדו בפעם הראשונה. הסיבה היחידה שאני יכול לכתוב בקלות טטריס אבל לא בטוח איך לכתוב גיט היא שכבר כתבתי משחקי טטריס בכמה שפות, ואף פעם לא כתבתי לקוח גיט. הדרך קדימה לכתוב דברים שעוד לא כתבתי בעבר עוברת בהכרח דרך רעיונות שעוד לא ניסיתי, ושאולי לא יעבדו. אותם רעיונות שלא בטוח יעבדו הם המפתח להתקדמות.
יותר מזה, אם הדבר היחיד שאני עושה בעבודה הוא לכתוב רק דברים שאני מכיר, מהר מאוד העבודה תהיה מאוד משעממת. אף אחד לא רוצה להישאר עשר שנים במקום שבו כל בוקר כותבים מחדש טטריס. רעיונות שלא בטוח יעבדו מוסיפים עניין ואושר לחיים, וזה חלק מהדברים שאנחנו צריכים כבני אדם.
ובכל זאת רבים מאיתנו חוששים מרעיונות שלא בטוח יעבדו ולא בטוחים איך להגיע אליהם ולשלב אותם בחיי היום יום. הנה שלושה מפתחות שיעזרו לנו לשלב רעיונות כאלה בחיי היום יום:
## רעיונות שלא עובדים צריכים זמן
המפתח הראשון הוא המסגרת - המקום והזמן, שבו מותר לנסות דברים שלא בטוח יעבדו. אם תלמיד שואל אותי שאלה בקורס הוא מצפה לקבל תשובה אמינה. זאת לא סיטואציה שבה רצוי לנחש רעיון שלא בדקתי. אפילו בשאלות שאני לא יודע עדיף להגיד את זה בצורה ישירה, להגיד שאבדוק ולחזור עם תשובה שעובדת.
לעומת זאת אם אני יושב בבית ובונה לקוח גיט, אין שום בעיה שאני מנסה רעיון, הרעיון הזה לא מצליח. אפשר למחוק את כל הקוד ולהתחיל מחר שוב בכיוון אחר.
בשביל לשלב רעיונות שלא בטוח עובדים בחיים שלנו אנחנו רוצים לתת להם את המקום והזמן שבו הם יוכלו להרגיש בנוח, ואנחנו נוכל להרגיש איתם בנוח.
## רעיונות שלא עובדים לא אוהבים שמודדים אותם
המפתח השני הוא המטרה, או מה אני מנסה להשיג עם רעיונות שלא בטוח עובדים. אם הגישה שלי היא שזמן שמושקע בכתיבת קוד חייב "להחזיר את ההשקעה" אז יהיה לי קשה מאוד לבזבז 3 שעות על ניסיון לבנות לקוח גיט שלא יעבוד. סיכוי טוב שאני אפילו לא אתחיל כי איזה החזר השקעה בכלל אפשר לקבל מפרויקט כזה.
ובדיוק מהגישה הבית ספרית הזאת אנחנו רוצים להיפרד.
מימוש רעיונות שלא בטוח יעבדו בתוך המקום והזמן שמוקדש להם הוא המטרה. אני בונה את זה כדי לבנות את זה, ואם בסוף גם יצא פרויקט זה אחלה, אבל גם אם לא זה ממש בסדר.
הבלוג הזה הוא דוגמה למשחק שלי עם רעיונות שלא בטוח עובדים. אני כותב כל יום, חלק מהפוסטים מדברים לאנשים וחלק לא, וזה מעולה. אני לא מסתכל כמה אנשים נכנסים לקרוא פוסט או משתפים אותו כי זאת לא המטרה. הכתיבה היא המטרה של עצמה.
## אפשר (וכדאי) ליישם רעיונות שלא עובדים בכל תחום בחיים
תרגול עוזר, וגם שילוב רעיונות שלא בטוח עובדים בחיים שלנו זו מיומנות שדורשת תרגול. יכול להיות שבעבודה המקצועית שלכם אתם לא רואים עכשיו שום מקום שבו אפשר לנסות רעיונות שלא בטוח עובדים. יכול להיות שאתם מרגישים שמודדים כל צעד שלכם ושאתם בארגון שלא מאפשר לכם את החופש שאתם רוצים. יש הרבה מקומות כאלה.
הפיתרון הוא להתחיל מאזורים אחרים בחיים שאולי בהם יש לכם יותר חופש - עם המשפחה, בשעות הפנאי, בתחביבים. אם יש לכם ילדים קטנים תוכלו להחליט שפעם בשבוע תאספו את הילדים מהמסגרת לפעילות קצרה שעדיין לא ניסיתם איתם ושהם אולי לא יאהבו. או אם אתם אוהבים ספורט תוכלו להחליט שפעם בשבוע או שבועיים תנסו סוג אימון חדש שעוד לא ניסיתם ואולי לא תאהבו.
מה שיפה ברעיונות זה שככל שאנחנו נותנים להם את המקום והזמן, ככל שאנחנו לא מודדים אותם, וככל שאנחנו מנסים יותר מהם, כך יותר קל לחשוב על רעיונות חדשים. ולאט לאט מעגל הקסמים מתרחב ואנחנו מגלים את הכיף ביישום רעיונות שלא בטוח עובדים ביותר ויותר תחומים בחיים.
1 419
# ככה עושים דברים פה אצלנו
מתכנתים רבים מרגישים שהיתרון הגדול בפריימוורק הוא שהיא עונה על השאלה "איך עושים דברים פה בפרויקט". מה צריך לעשות בשביל להוסיף פיצ'ר, מה המקום הנכון לתקן באג, איך כותבים את הבדיקות והתיעוד. עם פריימוורק טוב מתכנתים חדשים נכנסים מהר לפרויקט ויודעים בדיוק איך צריך לכתוב.
ורבים אחרים מרגישים שפריימוורק פוגע בתחזוקה לאורך זמן. ששימוש בפריימוורק מאפשר לבנות התחלה של מערכת מהר, אבל ככל שהפרויקט גדל הפריימוורק (כל פריימוורק) יהפוך "קטן מדי" על הפרויקט ובהכרח פיצ'רים מתקדמים ידרשו הרבה יותר מאמץ. לא רק זה, אלא ששידרוג לפי לוח הזמנים של הפריימוורק עלול לגזול זמן שהיה עדיף להשקיע בקוד שלך. אותם מתכנתים מרגישים שכשהקוד הוא 100% שלנו אז אנחנו במקום הרבה יותר טוב להחליט איך עושים דברים פה בפרויקט.
האמת היא שהפריימוורק הוא לא העניין פה.
לכל פריימוורק שתיקחו יש מספיק פרויקטים שהשתמשו בה והסתבכו. יש מספיק מתכנתים שהגיעו לפרויקט ושברו חוקים של הפריימוורק בלי לדעת בכלל שזה מה שהם עושים, והמון מקומות בהם באמת היה צריך עקרונות בסיסיים בפריימוורק כדי להתאים לפרויקט. הפריימוורק לא מבטיח שדברים יבוצעו בצורה מסוימת.
ומצד שני כשאין פריימוורק פרויקטים מורכבים הופכים אקלקטיים, מתכנתים חדשים נכנסים ומביאים את הסגנון שלהם ולאורך זמן קשה להכניס אנשים וגם פרויקטים אלה הופכים לכדור בוץ גדול.
פריימוורק הוא לא הבעיה וגם לא הפיתרון.
במקום להתמקד בכלים כדאי להתחיל בתשובה לשאלה "איך עושים דברים פה אצלנו". וכן רצוי להיות ספציפיים וגם לכתוב את זה. תוכלו להוסיף לאותו מסמך דוגמאות מקרה של שינויים או תיקונים שהוכנסו, התלבטויות בין כמה אופציות והסבר למה נבחרה האופציה שנבחרה. וכן יש להשאיר את המסמך או אוסף המסמכים הזה חי על ידי עדכון שוטף שלו.
המטרה שלנו היא שתהיה לכל מתכנת ומתכנתת בצוות תשובות זמינות לשאלה "איך עושים דברים פה בפרויקט", ושהתשובות האלה יהיו כמה שיותר עקביות.
1 419
# המקום הנכון לתיקון
כשאתם רואים סרט ביוטיוב ורוצים להגביר את הווליום יש שני כפתורים שאפשר ללחוץ עליהם: יש את כפתור הווליום הקטן ליד הסרט, ואת כפתור הווליום הראשי של המחשב. הגבירו את הלא נכון והסרט אומנם יתחיל לדבר חזק יותר, אבל גם הנוטיפיקציה הבאה שתקבלו עלולה לעשות רעש יותר מבהיל ממה שאתם רגילים.
וכן הזן של פייתון משקר. כשהם כותבים:
> There should be one-- and preferably only one --obvious way to do it.
הם לא באמת מתכוונים לזה, כי גם בפייתון וגם בכל שפת תכנות שנבחר, בדיוק כמו בווליום ביוטיוב, יש הרבה דרכים לעשות כל דבר ולכל דרך יש את הניואנסים שלה. ובדיוק כמו בווליום ביוטיוב, באותו רגע שהסרט חלש לא לגמרי ברור מה ההבדל בין הדרכים. שני הכפתורים עושים רושם של להגביר.
זו תהיה טעות "להתעלם" מאופציה אחת, להגיד "אני תמיד מגביר או מנמיך דרך הכפתור שליד הסרט" (או הכללי של המחשב). המטרה שלנו כאנשי מקצוע היא לחפש את הפרטים. להבין כמה שיותר דרכים בהן אפשר לתקן באג או לבנות פיצ'ר, להבין את ההבדלים הדקים בין הדרכים ולבחור את הדרך שמתאימה ביותר למצב המסוים שלנו.
וכן במחשבה שניה על הזן של פייתון, אפשר להגיד שיש דרך ברורה לתקן את הבאג או לבנות את הפיצ'ר בתוך Use Case ספציפי, אבל בשביל לראות אותה צריך הרבה עבודת מחקר (או להיוולד הולנדים).
1 419
# טיפ ריאקט: טיפול באירועים גלובאליים
בריאקט מאוד קל לטפל באירועים ברמת הקומפוננטה - צריך רק להוסיף מאפיין
on ושם האירוע. למשל בשביל לטפל באירוע keydown על אלמנט בתוך קומפוננטת ריאקט אני יכול לכתוב:
export default function App() {
const [keys, setKeys] = useState("");
function handleKeyDown(e) {
setKeys(keys + e.key);
}
return (
<div className="App" onKeyDown={handleKeyDown}>
<h1>Hello CodeSandbox</h1>
<h2>Start editing to see some magic happen!</h2>
<p>{keys}</p>
<input type="text" />
</div>
);
}
אבל זה רק חצי עובד: קוד כזה יפעיל את פונקציית הטיפול באירוע רק אם משהו בתוך הקומפוננטה נמצא בפוקוס. לכן כשתיבת הטקסט בפוקוס ואנחנו כותבים שם טקסט גם משתנה ה state יתעדכן, אבל במצבים אחרים כשאני פשוט לוחץ על כפתורים הקומפוננטה תתעלם מהלחיצות.
הפיתרון כאן הוא הרבה יותר קל ממה שאפשר לדמיין. אנחנו הרי יודעים שכל אירוע גלובאלי מגיע ל body, ובפרט אירועי keydown, כשאין אף אלמנט בפוקוס פשוט מטופלים ברמת ה body. כל מה שצריך לכן הוא להוסיף אפקט שיתחבר לאירוע ה keydown של ה body בכניסה למסך של הקומפוננטה, ויתנתק ביציאה.
בשביל שיהיה נוח להשתמש בקוד מכל מקום ביישום, אני אוהב לכתוב קוד "אפקט" כזה בתוך קומפוננטה נפרדת, ואז לשתול את הקומפוננטה בכל מקום שצריך אותה. וכן, אפשר גם לכתוב Custom Hook ולקבל בדיוק את אותו אפקט. זה הקוד אחרי התיקון:
import { useEffect, useState } from "react";
import "./styles.css";
function GlobalKeyboardEvents({ onKeyDown }) {
useEffect(() => {
document.body.addEventListener("keydown", onKeyDown);
return function () {
document.body.removeEventListener("keydown", onKeyDown);
};
}, [onKeyDown]);
return <></>;
}
export default function App() {
const [keys, setKeys] = useState("");
function handleKeyDown(e) {
setKeys(keys + e.key);
}
return (
<div className="App" >
<h1>Hello CodeSandbox</h1>
<h2>Start editing to see some magic happen!</h2>
<p>{keys}</p>
<input type="text" />
<GlobalKeyboardEvents onKeyDown={handleKeyDown} />
</div>
);
}
ואפשר לשחק איתו לייב בארגז החול בקישור:
https://codesandbox.io/s/frosty-violet-llfo2g?file=/src/App.js:0-7111 419
# מחשבות שמאטות אותי
לפני שעזבתי את העבודה בתור שכיר כשכבר הייתי עם רגל אחת בחוץ, תפס אותי חבר מהעבודה שם לשיחה. "איך יש לך אומץ?" הוא שאל, "ואם זה לא יצליח?", "את הכסף שתפסיד על הניסיון אולי לעולם לא תקבל חזרה. אתה מסכן את כל העתיד שלך".
קל לראות איך מחשבה כזאת יוצרת פחדים, חרדות, ומוציאה את המוטיבציה לנסות. ובלי לנסות קשה מאוד להצליח. (לשמחתו של אותו חבר בסופו של דבר גם הוא התגבר על הפחד, פתח סטארט-אפ משלו ולא מסתכל אחורה).
"לענות טעות זה יותר גרוע מלא לענות כלום" היא עוד מחשבה מהסוג הזה, ואחותה הקטנה "עדיף לחכות עד שאהיה בטוחה". שתי המחשבות האלה יוצרות אקלים רגשי של פחד ויכולות להכשיל אותך בראיון עבודה יותר מכל שאלה של המראיינת. יותר גרוע, אנשים שמאמינים בזה יוותרו על לשלוח קורות חיים למשרה אם הם לא עונים על כל הקריטריונים במודעה ב 150%, מה שכבר סוגר מראש הרבה הזדמנויות.
מתכנתים ומתכנתות רבים בטוחים ש"הלימוד הכי טוב הוא דרך כתיבת קוד" ולכן "קריאת תיעוד או קוד מקור של ספריה זה בזבוז זמן", או האחות הקטנה שלה "למי שעובד במשרה מלאה אין זמן ללמוד". אמונות כאלה דוחפות אותך "לנוח" בטיקטוק במקום למצוא דרכי לימוד והעשרה שיתאימו ללו"ז שלך.
ומתכנתות רבות מרגישות ש"בשביל להתקדם צריך לתת יותר שעות" וש"משרה עם יותר אחריות תבוא על חשבון דברים אחרים שחשובים לי בחיים". עם אמונה כזאת קשה לנצל הזדמנויות גם כשהן מופיעות, והמוח נוטה להתמקד בדוגמאות של אנשים שעובדים יותר מדי שעות על חשבון החיים הפרטיים רק בשביל לחזק את אותן אמונות.
זה לא קל לשנות אמונה שמאטה אותך כי ברוב המקרים המוח ממש מתנגד לכזה שינוי. ובכל זאת רוב הזמן שווה למצוא את הדרך לזהות ולשנות את אותן מחשבות. כשהמח פועל נגדך הרבה יותר קשה להתקדם.
¡Ya disponible! Investigación de Telegram 2025 — los principales insights del año 
