נראה כמו קומפוננטה

05/04/2021

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

function createBox(props) {
    const style = {
        display: 'inline-block',
        border: '1px solid',
        width: '80px',
        height: '80px',
        verticalAlign: 'top',
        ...props.style,
    };

    return (
        <div style={style} {...props} />
    );
}

function App() {
    return (
        <div>
            {_.range(10).map(() => createBox())}
        </div>
    );
}

הפונקציה App היא אכן קומפוננטה ומחזירה מערך של 10 div-ים עם עיצוב מתאים. הפונקציה createDiv יותר בעייתית: היא אינה קומפוננטה אבל היא נראית קצת כמו והיא מסבכת אותנו כשצריך לעשות Refactor. אם בעתיד נצטרך לשמור סטייט בתוך הקופסאות האלה ונרצה להוסיף קריאה ל useState לתוך הפונקציה, אז הסטייט יישמר בקומפוננטה שקוראת לפונקציה כלומר ב App. בגלל שהפונקציה לא נראית כמו Custom Hook קל להתבלבל ולהפעיל אותה מתוך תנאי או לולאה מה שיגרום לתוצאות לא צפויות.

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

function Box(props) {
    const style = {
        display: 'inline-block',
        border: '1px solid',
        width: '80px',
        height: '80px',
        verticalAlign: 'top',
        ...props.style,
    };

    return (
        <div style={style} {...props} />
    );
}

function App() {
    return (
        <div>
            {_.range(10).map(() => <Box />)}
        </div>
    );
}