$30 off During Our Annual Pro Sale. View Details »

Solid for React Developers

Solid for React Developers

In 2023, Solid JS is poised to be the next big frontend framework. Its underlying fundamentals are fundamentally different from React's. This talk will expose my learnings as I have approached Solid from the perspective of a React developer.

Erik Rasmussen

September 29, 2023
Tweet

More Decks by Erik Rasmussen

Other Decks in Programming

Transcript

  1. 2023
    SolidJS


    For React Developers
    Erik Rasmussen

    View Slide

  2. 2023
    SolidJS


    For React Developers
    Erik Rasmussen

    View Slide

  3. Erik Rasmussen – @erikras
    React Developer

    View Slide

  4. Erik Rasmussen – @erikras
    Solid Developer (yet)

    View Slide

  5. Erik Rasmussen – @erikras
    Imperative Programming
    HOW

    View Slide

  6. Erik Rasmussen – @erikras
    Imperative Programming
    $(document).ready(()
    =
    {


    });


    View Slide

  7. Erik Rasmussen – @erikras
    Imperative Programming
    $(document).ready(()
    =
    {


    $('button')


    });


    View Slide

  8. Erik Rasmussen – @erikras
    Imperative Programming
    $(document).ready(()
    =
    {


    $('button').on('click', ()
    =
    {


    })


    });


    View Slide

  9. Erik Rasmussen – @erikras
    Imperative Programming
    $(document).ready(()
    =
    {


    $('button').on('click', ()
    =
    {


    $('#greeting')


    })


    });


    View Slide

  10. Erik Rasmussen – @erikras
    Imperative Programming
    $(document).ready(()
    =
    {


    $('button').on('click', ()
    =
    {


    $('#greeting').addClass('highlighted')


    })


    });


    View Slide

  11. Erik Rasmussen – @erikras
    Declarative Programming
    WHAT

    View Slide

  12. Erik Rasmussen – @erikras
    Declarative Programming
    function App() {


    const [highlighted, setHighlighted] = React.useState(false);


    return (





    Highlight


    Hello!





    );


    }

    View Slide

  13. Erik Rasmussen – @erikras
    Declarative Programming
    function App() {


    const [highlighted, setHighlighted] = React.useState(false);


    return (





    =
    setHighlighted(true)}>Highlight


    Hello!





    );


    }

    View Slide

  14. Erik Rasmussen – @erikras
    Declarative Programming
    function App() {


    const [highlighted, setHighlighted] = React.useState(false);


    return (





    =
    setHighlighted(true)}>Highlight


    Hello!





    );


    }

    View Slide

  15. Erik Rasmussen – @erikras
    Reactive Programming
    is a declarative programming paradigm
    built on data-centric event emitters
    – Ryan Carniato
    @ryancarniato

    View Slide

  16. Erik Rasmussen – @erikras
    Reactive Programming
    let a = 3;


    let b = 4;


    let sum = a + b;


    console.log(sum); // 7
    Imperative Programming

    View Slide

  17. Erik Rasmussen – @erikras
    Reactive Programming
    let a = 3;


    let b = 4;


    let sum = a + b;


    console.log(sum); // 7


    a = 5;


    Imperative Programming

    View Slide

  18. Erik Rasmussen – @erikras
    Reactive Programming
    let a = 3;


    let b = 4;


    let sum = a + b;


    console.log(sum); // 7


    a = 5;


    console.log(sum); // 7
    Imperative Programming
    🙄

    View Slide

  19. Erik Rasmussen – @erikras
    Reactive Programming
    let a = 3;


    let b = 4;


    let sum = a + b;


    console.log(sum); // 7


    a = 5;


    console.log(sum); // 9
    Imperative Programming
    🤯

    View Slide

  20. Erik Rasmussen – @erikras
    Reactive Programming
    let a = ()
    =>
    3;


    let b = ()
    =>
    4;


    let sum = ()
    =>
    a() + b();


    console.log(sum()); // 7


    View Slide

  21. Erik Rasmussen – @erikras
    Reactive Programming
    let a = ()
    =>
    3;


    let b = ()
    =>
    4;


    let sum = ()
    =>
    a() + b();


    console.log(sum()); // 7


    a = ()
    =
    5;


    console.log(sum()); // 9
    😎

    View Slide

  22. Erik Rasmussen – @erikras
    Signals

    View Slide

  23. Erik Rasmussen – @erikras
    Signal
    a value that remembers everyone
    that reads it, and informs them
    when the value changes
    – Erik Rasmussen
    @erikras

    View Slide

  24. Erik Rasmussen – @erikras
    Signals in Solid
    const [value, setValue] = createSignal(0);


    View Slide

  25. Erik Rasmussen – @erikras
    Signals in Solid
    const [value, setValue] = createSignal(0);


    console.log(value()); // 0


    View Slide

  26. Erik Rasmussen – @erikras
    Signals in Solid
    const [value, setValue] = createSignal(0);


    console.log(value()); // 0


    setValue(42);


    console.log(value()); // 42
    FOOTGUN #1:


    Signal values are getter


    functions!

    View Slide

  27. Erik Rasmussen – @erikras
    Signals in Solid
    const [value, setValue] = createSignal(0);


    console.log(value()); // 0


    setValue(42);


    console.log(value()); // 42

    View Slide

  28. Erik Rasmussen – @erikras
    Signals in Solid
    const [getValue, setValue] = createSignal(0);


    console.log(getValue()); // 0


    setValue(42);


    console.log(getValue()); // 42

    View Slide

  29. Erik Rasmussen – @erikras
    Signals in Solid
    const [value, setValue] = createSignal(0);


    console.log(value()); // 0


    setValue(42);


    console.log(value()); // 42

    View Slide

  30. Erik Rasmussen – @erikras
    Derived Signals in Solid
    const [count, setCount] = createSignal(0);


    const double = ()
    =>
    count() * 2;


    View Slide

  31. Erik Rasmussen – @erikras
    Derived Signals in Solid
    const [count, setCount] = createSignal(0);


    const double = ()
    =>
    count() * 2;


    const increment = ()
    =>
    setCount(count() + 1);


    View Slide

  32. Erik Rasmussen – @erikras
    Derived Signals in Solid
    const [count, setCount] = createSignal(0);


    const double = ()
    =>
    count() * 2;


    const increment = ()
    =>
    setCount(count() + 1);


    console.log(count(), double()); // 0 0


    increment();


    console.log(count(), double()); // 1 2


    increment();


    console.log(count(), double()); // 2 4

    View Slide

  33. Erik Rasmussen – @erikras
    Spreadsheets

    View Slide

  34. Erik Rasmussen – @erikras
    The Elephant in the Room

    View Slide

  35. Erik Rasmussen – @erikras
    But... React
    isn't
    "reactive"!

    View Slide

  36. Erik Rasmussen – @erikras
    React Solid
    export const MyComponent = ()
    =>
    {


    return (





    Pop Quiz


    What library is this?





    );


    };
    export const MyComponent = ()
    =>
    {


    return (





    Pop Quiz


    What library is this?





    );


    };

    View Slide

  37. Erik Rasmussen – @erikras
    React Solid
    export const MyComponent = ()
    =>
    {


    return (





    Pop Quiz


    What library is this?





    );


    };
    export const MyComponent = ()
    =>
    {


    return (





    Pop Quiz


    What library is this?





    );


    };

    View Slide

  38. Erik Rasmussen – @erikras
    React Solid
    • Divide UI into "components"

    • Components are just functions

    • Components take props

    • Components output JSX

    • Component composition via JSX
    BOTH

    View Slide

  39. Erik Rasmussen – @erikras
    React Solid
    THE UBIQUITOUS COUNTER EXAMPLE
    export const Counter = ()
    =>
    {


    const [count, setCount] = useState(0);


    return (





    {count}




    ()
    =
    setCount(count + 1)


    }>➕





    );


    };
    export const Counter = ()
    =>
    {


    const [count, setCount] = createSignal(0);


    return (





    {count()}




    ()
    =
    setCount(count() + 1)


    }>➕





    );


    };

    View Slide

  40. Erik Rasmussen – @erikras
    React Solid
    THE UBIQUITOUS COUNTER EXAMPLE
    export const Counter = ()
    =>
    {


    const [count, setCount] = useState(0);


    return (





    {count}




    ()
    =
    setCount(count + 1)


    }>➕





    );


    };
    export const Counter = ()
    =>
    {


    const [count, setCount] = createSignal(0);


    return (





    {count()}




    ()
    =
    setCount(count() + 1)


    }>➕





    );


    };

    View Slide

  41. Erik Rasmussen – @erikras
    React Solid
    THE UBIQUITOUS COUNTER EXAMPLE
    export const Counter = ()
    =>
    {


    const [count, setCount] = useState(0);


    return (





    {count}




    ()
    =
    setCount(count + 1)


    }>➕





    );


    };
    export const Counter = ()
    =>
    {


    const [count, setCount] = createSignal(0);


    return (





    {count()}




    ()
    =
    setCount(count() + 1)


    }>➕





    );


    };

    View Slide

  42. Erik Rasmussen – @erikras
    React Solid
    THE UBIQUITOUS COUNTER EXAMPLE
    export const Counter = ()
    =>
    {


    const [count, setCount] = useState(0);


    return (





    {count}




    ()
    =
    setCount(count + 1)


    }>➕





    );


    };
    export const Counter = ()
    =>
    {


    const [count, setCount] = createSignal(0);


    return (





    {count()}




    ()
    =
    setCount(count() + 1)


    }>➕





    );


    };

    View Slide

  43. Erik Rasmussen – @erikras
    React Solid
    THE UBIQUITOUS COUNTER EXAMPLE
    export const Counter = ()
    =>
    {


    const [count, setCount] = useState(0);


    return (





    {count}




    setCount((previous)
    =
    previous + 1)


    }>➕





    );


    };
    export const Counter = ()
    =>
    {


    const [count, setCount] = createSignal(0);


    return (





    {count()}




    ()
    =
    setCount(count() + 1)


    }>➕





    );


    };

    View Slide

  44. Erik Rasmussen – @erikras
    React Solid
    THE UBIQUITOUS COUNTER EXAMPLE
    export const Counter = ()
    =>
    {


    const [count, setCount] = useState(0);


    return (





    {count}




    setCount((previous)
    =
    previous + 1)


    }>➕





    );


    };
    export const Counter = ()
    =>
    {


    const [count, setCount] = createSignal(0);


    return (





    {count()}




    setCount((previous)
    =
    previous + 1)


    }>➕





    );


    };

    View Slide

  45. Erik Rasmussen – @erikras
    React Solid
    THE UBIQUITOUS COUNTER EXAMPLE
    export const Counter = ()
    =>
    {


    const [count, setCount] = useState(0);


    return (





    {count}




    setCount((previous)
    =
    previous + 1)


    }>➕





    );


    };
    export const Counter = ()
    =>
    {


    const [count, setCount] = createSignal(0);


    return (





    {count()}




    setCount((previous)
    =
    previous + 1)


    }>➕





    );


    };

    View Slide

  46. Erik Rasmussen – @erikras
    React Solid
    THE UBIQUITOUS TIMER EXAMPLE
    export const Counter = ()
    =>
    {


    const [count, setCount] = useState(0);


    return (





    {count}




    (previous)
    =
    setCount(previous + 1)


    }>➕





    );


    };


    export const Counter = ()


    const [count, setCount] = createSignal(0);


    return (





    {count()}




    (previous)


    }>➕





    );


    };

    View Slide

  47. Erik Rasmussen – @erikras
    React Solid
    THE UBIQUITOUS TIMER EXAMPLE
    export const Counter = ()
    =>
    {


    const [count, setCount] = useState(0);


    return (





    {count}





    );


    };


    export const Counter = ()


    const [count, setCount] = createSignal(0);


    return (





    {count()}




    (previous)


    }>➕





    );


    };

    View Slide

  48. Erik Rasmussen – @erikras
    React Solid
    THE UBIQUITOUS TIMER EXAMPLE
    export const Counter = ()
    =>
    {


    const [count, setCount] = useState(0);


    useEffect(()
    =>
    {


    })


    return (





    {count}





    );


    };


    export const Counter = ()


    const [count, setCount] = createSignal(0);


    return (





    {count()}




    (previous)


    }>➕





    );


    };

    View Slide

  49. Erik Rasmussen – @erikras
    React Solid
    THE UBIQUITOUS TIMER EXAMPLE
    export const Counter = ()
    =>
    {


    const [count, setCount] = useState(0);


    useEffect(()
    =>
    {


    const interval = setInterval(()
    =>
    {


    setCount(count + 1);


    }, 1000);


    });


    return (





    {count}





    );


    };


    export const Counter = ()


    const [count, setCount] = createSignal(0);


    return (





    {count()}




    (previous)


    }>➕





    );


    };

    View Slide

  50. Erik Rasmussen – @erikras
    React Solid
    THE UBIQUITOUS TIMER EXAMPLE
    export const Counter = ()
    =>
    {


    const [count, setCount] = useState(0);


    useEffect(()
    =>
    {


    const interval = setInterval(()
    =>
    {


    setCount(count + 1);


    }, 1000);


    return ()
    =>
    clearInterval(interval);


    });


    return (





    {count}





    );


    };
    export const Counter = ()


    const [count, setCount] = createSignal(0);


    return (





    {count()}




    (previous)


    }>➕





    );


    };

    View Slide

  51. Erik Rasmussen – @erikras
    React Solid
    THE UBIQUITOUS TIMER EXAMPLE
    export const Counter = ()
    =>
    {


    const [count, setCount] = useState(0);


    useEffect(()
    =>
    {


    const interval = setInterval(()
    =>
    {


    setCount(count + 1);


    }, 1000);


    return ()
    =>
    clearInterval(interval);


    }, [count]);


    return (





    {count}





    );


    };
    export const Counter = ()


    const [count, setCount] = createSignal(0);


    return (





    {count()}




    (previous)


    }>➕





    );


    };

    View Slide

  52. Erik Rasmussen – @erikras
    React Solid
    THE UBIQUITOUS TIMER EXAMPLE
    export const Counter = ()
    =>
    {


    const [count, setCount] = useState(0);


    useEffect(()
    =>
    {


    const interval = setInterval(()
    =>
    {


    setCount((previous)
    =>
    previous + 1);


    }, 1000);


    return ()
    =>
    clearInterval(interval);


    }, []);


    return (





    {count}





    );


    };
    export const Counter = ()


    const [count, setCount] = createSignal(0);


    return (





    {count()}




    (previous)


    }>➕





    );


    };

    View Slide

  53. Erik Rasmussen – @erikras
    React Solid
    THE UBIQUITOUS TIMER EXAMPLE
    export const Counter = ()
    =>
    {


    const [count, setCount] = useState(0);


    useEffect(()
    =>
    {


    const interval = setInterval(()
    =>
    {


    setCount((previous)
    =>
    previous + 1);


    }, 1000);


    return ()
    =>
    clearInterval(interval);


    }, []);


    return (





    {count}





    );


    };
    export const Counter = ()
    =>
    {


    const [count, setCount] = createSignal(0);


    return (





    {count()}




    (previous)
    =
    setCount(previous + 1)


    }>➕





    );


    };

    View Slide

  54. Erik Rasmussen – @erikras
    React Solid
    THE UBIQUITOUS TIMER EXAMPLE
    export const Counter = ()
    =>
    {


    const [count, setCount] = useState(0);


    useEffect(()
    =>
    {


    const interval = setInterval(()
    =>
    {


    setCount((previous)
    =>
    previous + 1);


    }, 1000);


    return ()
    =>
    clearInterval(interval);


    }, []);


    return (





    {count}





    );


    };
    export const Counter = ()
    =>
    {


    const [count, setCount] = createSignal(0);


    return (





    {count()}





    );


    };


    View Slide

  55. Erik Rasmussen – @erikras
    React Solid
    THE UBIQUITOUS TIMER EXAMPLE
    export const Counter = ()
    =>
    {


    const [count, setCount] = useState(0);


    useEffect(()
    =>
    {


    const interval = setInterval(()
    =>
    {


    setCount((previous)
    =>
    previous + 1);


    }, 1000);


    return ()
    =>
    clearInterval(interval);


    }, []);


    return (





    {count}





    );


    };
    export const Counter = ()
    =>
    {


    const [count, setCount] = createSignal(0);


    setInterval(()
    =>
    {


    setCount((previous)
    =>
    previous + 1);


    });


    return (





    {count()}





    );


    };


    View Slide

  56. Erik Rasmussen – @erikras
    React Solid
    THE UBIQUITOUS TIMER EXAMPLE
    export const Counter = ()
    =>
    {


    const [count, setCount] = useState(0);


    useEffect(()
    =>
    {


    const interval = setInterval(()
    =>
    {


    setCount((previous)
    =>
    previous + 1);


    }, 1000);


    return ()
    =>
    clearInterval(interval);


    }, []);


    return (





    {count}





    );


    };
    export const Counter = ()
    =>
    {


    const [count, setCount] = createSignal(0);


    setInterval(()
    =>
    {


    setCount((previous)
    =>
    previous + 1);


    });


    onCleanup(()
    =>
    clearInterval(interval));


    return (





    {count()}





    );


    };


    View Slide

  57. Erik Rasmussen – @erikras
    React Solid
    THE UBIQUITOUS TIMER EXAMPLE
    export const Counter = ()
    =>
    {


    const [count, setCount] = useState(0);


    useEffect(()
    =>
    {


    const interval = setInterval(()
    =>
    {


    setCount((previous)
    =>
    previous + 1);


    }, 1000);


    return ()
    =>
    clearInterval(interval);


    }, []);


    return (





    {count}





    );


    };
    export const Counter = ()
    =>
    {


    const [count, setCount] = createSignal(0);


    setInterval(()
    =>
    {


    setCount((previous)
    =>
    previous + 1);


    });


    onCleanup(()
    =>
    clearInterval(interval));


    return (





    {count()}





    );


    };


    View Slide

  58. Erik Rasmussen – @erikras
    React Solid
    THE UBIQUITOUS TIMER EXAMPLE
    export const Counter = ()
    =>
    {


    const [count, setCount] = useState(0);


    useEffect(()
    =>
    {


    const interval = setInterval(()
    =>
    {


    setCount((previous)
    =>
    previous + 1);


    }, 1000);


    return ()
    =>
    clearInterval(interval);


    }, []);


    return (





    {count}





    );


    };
    export const Counter = ()
    =>
    {


    const [count, setCount] = createSignal(0);


    setInterval(()
    =>
    {


    setCount((previous)
    =>
    previous + 1);


    });


    onCleanup(()
    =>
    clearInterval(interval));


    return (





    {count()}





    );


    };


    FOOTGUN #2:


    The component function is


    only called once!

    View Slide

  59. Erik Rasmussen – @erikras
    React Solid
    THE UBIQUITOUS TIMER EXAMPLE
    export const Counter = ()
    =>
    {


    const [count, setCount] = useState(0);


    useEffect(()
    =>
    {


    const interval = setInterval(()
    =>
    {


    setCount((previous)
    =>
    previous + 1);


    }, 1000);


    return ()
    =>
    clearInterval(interval);


    }, []);


    return (





    {count}





    );


    };
    export const Counter = ()
    =>
    {


    const [count, setCount] = createSignal(0);


    setInterval(()
    =>
    {


    setCount((previous)
    =>
    previous + 1);


    });


    onCleanup(()
    =>
    clearInterval(interval));


    return (





    {count()}





    );


    };


    View Slide

  60. Erik Rasmussen – @erikras
    React Solid
    THE UBIQUITOUS TIMER EXAMPLE
    export const Counter = ()
    =>
    {


    const [count, setCount] = useState(0);


    useEffect(()
    =>
    {


    const interval = setInterval(()
    =>
    {


    setCount((previous)
    =>
    previous + 1);


    }, 1000);


    return ()
    =>
    clearInterval(interval);


    }, []);


    return (





    {count}





    );


    };
    export const Counter = ()
    =>
    {


    const [count, setCount] = createSignal(0);


    setInterval(()
    =>
    {


    setCount((previous)
    =>
    previous + 1);


    });


    onCleanup(()
    =>
    clearInterval(interval));


    return (





    {count()}





    );


    };


    HOOKS
    JSX
    RUN ON MOUNT
    JSX

    View Slide

  61. Erik Rasmussen – @erikras
    React
    Solid
    is "just JavaScript" that re-renders to Virtual
    DOM every time data changes, and performs a
    diff to know which DOM elements to update
    is a compiled template language that
    remembers which DOM elements
    depend on which state

    View Slide

  62. Erik Rasmussen – @erikras
    Solid
    export const Counter = ()
    =>
    {


    const [count, setCount] = createSignal(0);


    setInterval(()
    =>
    {


    setCount((previous)
    =>
    previous + 1);


    });


    onCleanup(()
    =>
    clearInterval(interval));


    return (





    {count()}





    );


    };


    View Slide

  63. Erik Rasmussen – @erikras
    Solid
    export const Counter = ()
    =>
    {


    const [count, setCount] = createSignal(0);


    setInterval(()
    =>
    {


    setCount((previous)
    =>
    previous + 1);


    });


    onCleanup(()
    =>
    clearInterval(interval));


    const doubleCount = count() * 2;


    return (





    {doubleCount}





    );


    };

    View Slide

  64. Erik Rasmussen – @erikras
    Solid
    export const Counter = ()
    =>
    {


    const [count, setCount] = createSignal(0);


    setInterval(()
    =>
    {


    setCount((previous)
    =>
    previous + 1);


    });


    onCleanup(()
    =>
    clearInterval(interval));


    const doubleCount = count() * 2;


    return (





    {doubleCount}





    );


    };
    1. Code before return happens
    only once!

    View Slide

  65. Erik Rasmussen – @erikras
    Solid
    export const Counter = ()
    =>
    {


    const [count, setCount] = createSignal(0);


    setInterval(()
    =>
    {


    setCount((previous)
    =>
    previous + 1);


    });


    onCleanup(()
    =>
    clearInterval(interval));


    const doubleCount = count() * 2;


    return (





    {doubleCount}





    );


    };
    1. Code before return happens
    only once!

    2. JSX should never output a
    value that's not a signal

    (because otherwise it would never update)
    FOOTGUN #3:


    Only use signals in JSX.


    Never "get" their value before


    the JSX.

    View Slide

  66. Erik Rasmussen – @erikras
    Props

    View Slide

  67. Erik Rasmussen – @erikras
    React Solid
    export const User = (props)
    =>
    {


    const { firstName, lastName, photoUrl } = props;


    return (







    src={photoUrl}


    alt={`${firstName} ${lastName}`} />


    {firstName} {lastName}





    );


    };
    PROPS
    export const User = (props)
    =>
    {


    const { firstName, lastName, photoUrl } = props;


    return (







    src={photoUrl}


    alt={`${firstName} ${lastName}`} />


    {firstName} {lastName}





    );


    };

    View Slide

  68. Erik Rasmussen – @erikras
    React Solid
    export const User = (props)
    =>
    {


    const { firstName, lastName, photoUrl } = props;


    return (







    src={photoUrl}


    alt={`${firstName} ${lastName}`} />


    {firstName} {lastName}





    );


    };
    PROPS
    export const User = (props)
    =>
    {


    const { firstName, lastName, photoUrl } = props;


    return (







    src={photoUrl}


    alt={`${firstName} ${lastName}`} />


    {firstName} {lastName}





    );


    };
    🧙
    {


    get firstName() {}


    get lastName() {}


    get photoUrl() {}


    }
    🚩
    FOOTGUN #3:


    Only use signals in JSX.


    Never "get" their value before


    the JSX.
    FOOTGUN #4:


    Never destructure props!

    View Slide

  69. Erik Rasmussen – @erikras
    React Solid
    export const User = (props)
    =>
    {


    const { firstName, lastName, photoUrl } = props;


    return (







    src={photoUrl}


    alt={`${firstName} ${lastName}`} />


    {firstName} {lastName}





    );


    };
    PROPS
    export const User = (props)
    =>
    {


    const { firstName, lastName, photoUrl } = props;


    return (







    src={photoUrl}


    alt={`${firstName} ${lastName}`} />


    {firstName} {lastName}





    );


    };

    View Slide

  70. Erik Rasmussen – @erikras
    React Solid
    export const User = (props)
    =>
    {


    const { firstName, lastName, photoUrl } = props;


    return (







    src={photoUrl}


    alt={`${firstName} ${lastName}`} />


    {firstName} {lastName}





    );


    };
    PROPS
    export const User = (props)
    =>
    {


    const { firstName, lastName, photoUrl } = props;


    return (







    src={props.photoUrl}


    alt={`${props.firstName} ${props.lastName}`} />


    {props.firstName} {props.lastName}





    );


    };

    View Slide

  71. Erik Rasmussen – @erikras
    React Solid
    export const User = (props)
    =>
    {


    const { firstName, lastName, photoUrl } = props;


    return (







    src={photoUrl}


    alt={`${firstName} ${lastName}`} />


    {firstName} {lastName}





    );


    };
    PROPS
    export const User = (props)
    =>
    {


    return (







    src={props.photoUrl}


    alt={`${props.firstName} ${props.lastName}`} />


    {props.firstName} {props.lastName}





    );


    };



    View Slide

  72. Erik Rasmussen – @erikras
    React Solid
    export const User = (props)
    =>
    {


    const {


    firstName = "Erik",


    lastName = "Rasmussen",


    photoUrl


    } = props;


    return (







    src={photoUrl}


    alt={`${firstName} ${lastName}`} />


    {firstName} {lastName}





    );


    };
    DEFAULT PROPS
    export const User = (props)
    =>
    {


    const {


    firstName = "Erik",


    lastName = "Rasmussen",


    photoUrl


    } = props;


    return (







    src={photoUrl}


    alt={`${firstName} ${lastName}`} />


    {firstName} {lastName}





    );


    };

    View Slide

  73. Erik Rasmussen – @erikras
    React Solid
    export const User = (props)
    =>
    {


    const {


    firstName = "Erik",


    lastName = "Rasmussen",


    photoUrl


    } = props;


    return (







    src={photoUrl}


    alt={`${firstName} ${lastName}`} />


    {firstName} {lastName}





    );


    };
    DEFAULT PROPS
    export const User = (props)
    =>
    {


    const {


    firstName = "Erik",


    lastName = "Rasmussen",


    photoUrl


    } = props;


    return (







    src={photoUrl}


    alt={`${firstName} ${lastName}`} />


    {firstName} {lastName}





    );


    };

    View Slide

  74. Erik Rasmussen – @erikras
    React Solid
    export const User = (props)
    =>
    {


    const {


    firstName = "Erik",


    lastName = "Rasmussen",


    photoUrl


    } = props;


    return (







    src={photoUrl}


    alt={`${firstName} ${lastName}`} />


    {firstName} {lastName}





    );


    };
    DEFAULT PROPS
    export const User = (props)
    =>
    {


    const merged = mergeProps(


    {


    firstName: "Erik",


    lastName: "Rasmussen",


    },


    props


    );


    return (







    src={photoUrl}


    alt={`${firstName} ${lastName}`}


    />


    {firstName} {lastName}





    );


    };

    View Slide

  75. Erik Rasmussen – @erikras
    React Solid
    export const User = (props)
    =>
    {


    const {


    firstName = "Erik",


    lastName = "Rasmussen",


    photoUrl


    } = props;


    return (







    src={photoUrl}


    alt={`${firstName} ${lastName}`} />


    {firstName} {lastName}





    );


    };
    DEFAULT PROPS
    export const User = (props)
    =>
    {


    const merged = mergeProps(


    {


    firstName: "Erik",


    lastName: "Rasmussen",


    },


    props


    );


    return (







    src={merged.photoUrl}


    alt={`${merged.firstName} ${merged.lastName}`}


    />


    {merged.firstName} {merged.lastName}





    );


    };

    View Slide

  76. Erik Rasmussen – @erikras
    Common Hooks

    View Slide

  77. Erik Rasmussen – @erikras
    React Solid
    useEffect is the single most
    dangerous hook in React
    – Erik Rasmussen
    @erikras
    probably plagiarizing David "Khourshid" 🎹
    @davidkpiano
    probably plagiarizing Dan Abramov
    @dan_abramov

    View Slide

  78. Erik Rasmussen – @erikras
    React Solid
    useE
    ff
    ect
    •Adding event listeners

    •Fetching data

    •Subscribing to data sources

    •Scheduling timeouts/intervals
    in component before return

    View Slide

  79. Erik Rasmussen – @erikras
    React Solid
    useE
    ff
    ect
    •Play a sound when data changes

    •Debounced save

    •Save state to localStorage
    createE
    ff
    ect

    View Slide

  80. Erik Rasmussen – @erikras
    React Solid
    export const Counter = ()
    =>
    {


    const [count, setCount] = useState(0);


    return (





    {count}




    onClick={(previous)
    =

    setCount(previous + 1)


    }


    >











    );


    };


    E
    ff
    ects

    View Slide

  81. Erik Rasmussen – @erikras
    React Solid
    export const Counter = ()
    =>
    {


    const [count, setCount] = useState(0);


    useEffect(()
    =>
    {


    console.log("Count is now:", count);


    });


    return (





    {count}




    onClick={(previous)
    =

    setCount(previous + 1)


    }


    >











    );


    };
    useE
    ff
    ect

    View Slide

  82. Erik Rasmussen – @erikras
    React Solid
    export const Counter = ()
    =>
    {


    const [count, setCount] = useState(0);


    useEffect(()
    =>
    {


    console.log("Count is now:", count);


    }, [count]);


    return (





    {count}




    onClick={(previous)
    =

    setCount(previous + 1)


    }


    >











    );


    };
    useE
    ff
    ect

    View Slide

  83. Erik Rasmussen – @erikras
    React Solid
    export const Counter = ()
    =>
    {


    const [count, setCount] = useState(0);


    useEffect(()
    =>
    {


    console.log("Count is now:", count);


    }, [count]);


    return (





    {count}




    onClick={(previous)
    =

    setCount(previous + 1)


    }


    >











    );


    };
    useE
    ff
    ect
    export const Counter = ()
    =>
    {


    const [count, setCount] = createSignal(0);


    return (





    {count()}




    onClick={(previous)
    =

    setCount(previous + 1)


    }


    >











    );


    };


    View Slide

  84. Erik Rasmussen – @erikras
    React Solid
    export const Counter = ()
    =>
    {


    const [count, setCount] = useState(0);


    useEffect(()
    =>
    {


    console.log("Count is now:", count);


    }, [count]);


    return (





    {count}




    onClick={(previous)
    =

    setCount(previous + 1)


    }


    >











    );


    };
    useE
    ff
    ect
    export const Counter = ()
    =>
    {


    const [count, setCount] = createSignal(0);


    createEffect(()
    =>
    {


    console.log("Count is now:", count());


    });


    return (





    {count()}




    onClick={(previous)
    =

    setCount(previous + 1)


    }


    >











    );


    };

    View Slide

  85. Erik Rasmussen – @erikras
    React Solid
    export const Counter = ()
    =>
    {


    const [count, setCount] = useState(0);


    useEffect(()
    =>
    {


    console.log("Count is now:", count);


    }, [count]);


    return (





    {count}




    onClick={(previous)
    =

    setCount(previous + 1)


    }


    >











    );


    };
    useE
    ff
    ect
    export const Counter = ()
    =>
    {


    const [count, setCount] = createSignal(0);


    createEffect(()
    =>
    {


    console.log("Count is now:", count());


    }, [count]);


    return (





    {count()}




    onClick={(previous)
    =

    setCount(previous + 1)


    }


    >











    );


    };

    View Slide

  86. Erik Rasmussen – @erikras
    React Solid
    export const Counter = ()
    =>
    {


    const [count, setCount] = useState(0);


    useEffect(()
    =>
    {


    console.log("Count is now:", count);


    }, [count]);


    return (





    {count}




    onClick={(previous)
    =

    setCount(previous + 1)


    }


    >











    );


    };
    useE
    ff
    ect
    export const Counter = ()
    =>
    {


    const [count, setCount] = createSignal(0);


    createEffect(()
    =>
    {


    console.log("Count is now:", count());


    });


    return (





    {count()}




    onClick={(previous)
    =

    setCount(previous + 1)


    }


    >











    );


    };
    NO DEPENDENCY ARRAY NEEDED!!

    View Slide

  87. Erik Rasmussen – @erikras
    React Solid
    export const Counter = ()
    =>
    {


    const [count, setCount] = useState(0);


    useEffect(()
    =>
    {


    console.log("Count is now:", count);


    }, [count]);


    return (





    {count}




    onClick={(previous)
    =

    setCount(previous + 1)


    }


    >











    );


    };
    useE
    ff
    ect
    export const Counter = ()
    =>
    {


    const [count, setCount] = createSignal(0);


    createEffect(()
    =>
    {


    console.log("Count is now:", count());


    });


    return (





    {count()}




    onClick={(previous)
    =

    setCount(previous + 1)


    }


    >











    );


    };

    View Slide

  88. Erik Rasmussen – @erikras
    React Solid
    export const Result = (props)
    =>
    {


    const expensiveResult =


    expensiveCalculation(props.value);


    return (








    The result is: {expensiveResult}








    );


    };


    useMemo

    View Slide

  89. Erik Rasmussen – @erikras
    React Solid
    export const Result = (props)
    =>
    {


    const expensiveResult = useMemo(


    ()
    =

    expensiveCalculation(props.value)


    );


    return (








    The result is: {expensiveResult}








    );


    };


    useMemo

    View Slide

  90. Erik Rasmussen – @erikras
    React Solid
    export const Result = (props)
    =>
    {


    const expensiveResult = useMemo(


    ()
    =

    expensiveCalculation(props.value),


    [props.value]


    );


    return (








    The result is: {expensiveResult}








    );


    };
    useMemo

    View Slide

  91. Erik Rasmussen – @erikras
    React Solid
    export const Result = (props)
    =>
    {


    const expensiveResult = useMemo(


    ()
    =

    expensiveCalculation(props.value),


    [props.value]


    );


    return (








    The result is: {expensiveResult}








    );


    };
    useMemo
    export const Result = (props)
    =>
    {


    const expensiveResult =


    expensiveCalculation(props.value);


    return (








    The result is: {expensiveResult}








    );


    };
    FOOTGUN #3:


    Only use signals in JSX.


    Never "get" their value before


    the JSX.

    View Slide

  92. Erik Rasmussen – @erikras
    React Solid
    export const Result = (props)
    =>
    {


    const expensiveResult = useMemo(


    ()
    =

    expensiveCalculation(props.value),


    [props.value]


    );


    return (








    The result is: {expensiveResult}








    );


    };
    useMemo
    export const Result = (props)
    =>
    {


    const expensiveResult = ()
    =>

    expensiveCalculation(props.value);


    return (








    The result is: {expensiveResult()}








    );


    };

    View Slide

  93. Erik Rasmussen – @erikras
    React Solid
    export const Result = (props)
    =>
    {


    const expensiveResult = useMemo(


    ()
    =

    expensiveCalculation(props.value),


    [props.value]


    );


    return (








    The result is: {expensiveResult}








    );


    };
    useMemo
    export const Result = (props)
    =>
    {


    const expensiveResult = ()
    =

    expensiveCalculation(props.value);


    return (





    Result: {expensiveResult()}


    Result: {expensiveResult()}


    Result: {expensiveResult()}





    );


    };

    View Slide

  94. Erik Rasmussen – @erikras
    React Solid
    export const Result = (props)
    =>
    {


    const expensiveResult = useMemo(


    ()
    =

    expensiveCalculation(props.value),


    [props.value]


    );


    return (








    The result is: {expensiveResult}








    );


    };
    useMemo
    export const Result = (props)
    =>
    {


    const expensiveResult = createMemo(


    ()
    =>
    expensiveCalculation(props.value)


    );


    return (





    Result: {expensiveResult()}


    Result: {expensiveResult()}


    Result: {expensiveResult()}





    );


    };

    View Slide

  95. Erik Rasmussen – @erikras
    React Solid
    export const Result = (props)
    =>
    {


    const expensiveResult = useMemo(


    ()
    =

    expensiveCalculation(props.value),


    [props.value]


    );


    return (








    The result is: {expensiveResult}








    );


    };
    useMemo
    export const Result = (props)
    =>
    {


    const expensiveResult = createMemo(


    ()
    =>
    expensiveCalculation(props.value),


    [props.value]


    );


    return (





    Result: {expensiveResult()}


    Result: {expensiveResult()}


    Result: {expensiveResult()}





    );


    };

    View Slide

  96. Erik Rasmussen – @erikras
    React Solid
    export const Result = (props)
    =>
    {


    const expensiveResult = useMemo(


    ()
    =

    expensiveCalculation(props.value),


    [props.value]


    );


    return (








    The result is: {expensiveResult}








    );


    };
    useMemo
    export const Result = (props)
    =>
    {


    const expensiveResult = createMemo(


    ()
    =>
    expensiveCalculation(props.value)


    );


    return (





    Result: {expensiveResult()}


    Result: {expensiveResult()}


    Result: {expensiveResult()}





    );


    };
    NO DEPENDENCY ARRAY NEEDED!!

    View Slide

  97. Erik Rasmussen – @erikras
    Flow Control

    View Slide

  98. Erik Rasmussen – @erikras

    View Slide

  99. Erik Rasmussen – @erikras
    React Solid
    export const LoginButton = (props)
    =>
    {


    return (





    {props.loggedIn ? (


    =
    props.logout()}>


    Logout





    ) : (


    =
    props.login()}>


    Login





    )}





    );


    };

    export const LoginButton = (props)
    =>
    {


    return (





    {props.loggedIn ? (


    =
    props.logout()}>


    Logout





    ) : (


    =
    props.login()}>


    Login





    )}





    );


    };

    View Slide

  100. Erik Rasmussen – @erikras
    React Solid
    export const LoginButton = (props)
    =>
    {


    return (





    {props.loggedIn ? (


    =
    props.logout()}>


    Logout





    ) : (


    =
    props.login()}>


    Login





    )}





    );


    };

    export const LoginButton = (props)
    =>
    {


    return (





    {props.loggedIn ? (


    =
    props.logout()}>


    Logout





    ) : (


    =
    props.login()}>


    Login





    )}





    );


    };

    View Slide

  101. Erik Rasmussen – @erikras
    React Solid
    export const LoginButton = (props)
    =>
    {


    return (





    {props.loggedIn ? (


    =
    props.logout()}>


    Logout





    ) : (


    =
    props.login()}>


    Login





    )}





    );


    };

    export const LoginButton = (props)
    =>
    {


    return (





    props.loggedIn


    =
    props.logout()}>


    Logout





    =
    props.login()}>


    Login








    );


    };


    View Slide

  102. Erik Rasmussen – @erikras
    React Solid
    export const LoginButton = (props)
    =>
    {


    return (





    {props.loggedIn ? (


    =
    props.logout()}>


    Logout





    ) : (


    =
    props.login()}>


    Login





    )}





    );


    };

    export const LoginButton = (props)
    =>
    {


    return (








    =
    props.logout()}>


    Logout








    =
    props.login()}>


    Login








    );


    };


    View Slide

  103. Erik Rasmussen – @erikras
    React Solid
    export const LoginButton = (props)
    =>
    {


    return (





    {props.loggedIn ? (


    =
    props.logout()}>


    Logout





    ) : (


    =
    props.login()}>


    Login





    )}





    );


    };

    export const LoginButton = (props)
    =>
    {


    return (







    when={props.loggedIn}


    fallback={


    =
    props.login()}>


    Login





    }


    >


    =
    props.logout()}>


    Logout











    );


    };

    View Slide

  104. Erik Rasmussen – @erikras
    /

    View Slide

  105. Erik Rasmussen – @erikras
    React Solid
    export const Results = (props)
    =>
    {


    return (





    {props.status
    =
    "pending" ? (





    ) : props.status
    =
    "loaded" ? (





    ) : (





    )}





    );


    };


    /
    export const Results = (props)
    =>
    {


    return (





    {props.status
    =
    "pending" ? (





    ) : props.status
    =
    "loaded" ? (





    ) : (





    )}





    );


    };


    View Slide

  106. Erik Rasmussen – @erikras
    React Solid
    export const Results = (props)
    =>
    {


    return (





    {props.status
    =
    "pending" ? (





    ) : props.status
    =
    "loaded" ? (





    ) : (





    )}





    );


    };


    /
    export const Results = (props)
    =>
    {


    return (





    {props.status
    =
    "pending" ? (





    ) : props.status
    =
    "loaded" ? (





    ) : (





    )}





    );


    };


    View Slide

  107. Erik Rasmussen – @erikras
    React Solid
    export const Results = (props)
    =>
    {


    return (





    {props.status
    =
    "pending" ? (





    ) : props.status
    =
    "loaded" ? (





    ) : (





    )}





    );


    };


    /
    export const Results = (props)
    =>
    {


    return (








    =
    "pending"}>








    props.status
    ===
    "loaded" ? (





    ) : (





    )}








    );


    };


    View Slide

  108. Erik Rasmussen – @erikras
    React Solid
    export const Results = (props)
    =>
    {


    return (





    {props.status
    =
    "pending" ? (





    ) : props.status
    =
    "loaded" ? (





    ) : (





    )}





    );


    };


    /
    export const Results = (props)
    =>
    {


    return (








    =
    "pending"}>








    =
    "loaded"}>











    )}








    );


    };


    View Slide

  109. Erik Rasmussen – @erikras
    React Solid
    export const Results = (props)
    =>
    {


    return (





    {props.status
    =
    "pending" ? (





    ) : props.status
    =
    "loaded" ? (





    ) : (





    )}





    );


    };


    /
    export const Results = (props)
    =>
    {


    return (





    }>


    =
    "pending"}>








    =
    "loaded"}>














    );


    };


    View Slide

  110. Erik Rasmussen – @erikras

    View Slide

  111. export const ItemList = (props)
    =>
    {


    return (





    {props.items.map(


    (item)
    =
    (





    {item.name}





    )


    )}





    );


    };
    Erik Rasmussen – @erikras
    React Solid

    export const ItemList = (props)
    =>
    {


    return (





    {props.items.map(


    (item)
    =
    (





    {item.name}





    )


    )}





    );


    };

    View Slide

  112. export const ItemList = (props)
    =>
    {


    return (





    {props.items.map(


    (item)
    =
    (





    {item.name}





    )


    )}





    );


    };
    Erik Rasmussen – @erikras
    React Solid

    export const ItemList = (props)
    =>
    {


    return (





    {props.items.map(


    (item)
    =
    (





    {item.name}





    )


    )}





    );


    };

    View Slide

  113. export const ItemList = (props)
    =>
    {


    return (





    {props.items.map(


    (item)
    =
    (





    {item.name}





    )


    )}





    );


    };
    Erik Rasmussen – @erikras
    React Solid

    export const ItemList = (props)
    =>
    {


    return (





    {props.items.map(


    (item)
    =
    (





    {item.name}





    )


    )}





    );


    };

    View Slide

  114. export const ItemList = (props)
    =>
    {


    return (





    {props.items.map(


    (item)
    =
    (





    {item.name}





    )


    )}





    );


    };
    Erik Rasmussen – @erikras
    React Solid

    export const ItemList = (props)
    =>
    {


    return (








    {(item)
    =
    (





    {item.name}





    )}








    );


    };
    NO KEY PROP NEEDED!!

    View Slide

  115. Erik Rasmussen – @erikras

    View Slide

  116. class ErrorBoundary extends React.Component {


    constructor(props) {


    super(props);


    this.state = { hasError: false };


    }


    static getDerivedStateFromError(error) {


    return { hasError: true };


    }


    componentDidCatch(error, info) {


    logError(error, info.componentStack);


    }


    render() {


    if (this.state.hasError) {


    return this.props.fallback;


    }


    return this.props.children;


    }


    }
    Erik Rasmussen – @erikras
    React Solid

    View Slide

  117. class ErrorBoundary extends React.Component {


    constructor(props) {


    super(props);


    this.state = { hasError: false };


    }


    static getDerivedStateFromError(error) {


    return { hasError: true };


    }


    componentDidCatch(error, info) {


    logError(error, info.componentStack);


    }


    render() {


    if (this.state.hasError) {


    return this.props.fallback;


    }


    return this.props.children;


    }


    }
    Erik Rasmussen – @erikras
    React Solid

    export const App = ()
    =>
    {


    return (







    fallback={(error)
    =
    (





    )}


    >











    );


    };
    🙄

    View Slide

  118. Erik Rasmussen – @erikras
    style prop

    View Slide

  119. Erik Rasmussen – @erikras
    React Solid
    style prop
    export const Text = ()
    =>
    {


    return (




    style={{


    fontWeight: "bold",


    margin: 15,


    maxHeight: "90vh",


    }}


    >


    Stylin'!





    );


    };
    export const Text = ()
    =>
    {


    return (




    style={{


    fontWeight: "bold",


    margin: 15,


    maxHeight: "90vh",


    }}


    >


    Stylin'!





    );


    };

    View Slide

  120. Erik Rasmussen – @erikras
    React Solid
    style prop
    export const Text = ()
    =>
    {


    return (




    style={{


    fontWeight: "bold",


    margin: 15,


    maxHeight: "90vh",


    }}


    >


    Stylin'!





    );


    };
    export const Text = ()
    =>
    {


    return (




    style={{


    fontWeight: "bold",


    margin: 15,


    maxHeight: "90vh",


    }}


    >


    Stylin'!





    );


    };

    View Slide

  121. Erik Rasmussen – @erikras
    React Solid
    style prop
    export const Text = ()
    =>
    {


    return (




    style={{


    fontWeight: "bold",


    margin: 15,


    maxHeight: "90vh",


    }}


    >


    Stylin'!





    );


    };
    export const Text = ()
    =>
    {


    return (




    style={{


    "font-weight": "bold",


    margin: "15px",


    "max-height": "90vh",


    }}


    >


    Stylin'!





    );


    };

    View Slide

  122. Erik Rasmussen – @erikras
    class prop

    View Slide

  123. Erik Rasmussen – @erikras
    React Solid
    class prop
    export const Table = ()
    =>
    {


    return (








    React


    Awesome








    Solid


    Also Awesome








    );


    };
    export const Table = ()
    =>
    {


    return (








    React


    Awesome








    Solid


    Also Awesome








    );


    };

    View Slide

  124. Erik Rasmussen – @erikras
    React Solid
    class prop
    export const Table = ()
    =>
    {


    return (








    React


    Awesome








    Solid


    Also Awesome








    );


    };
    export const Table = ()
    =>
    {


    return (








    React


    Awesome








    Solid


    Also Awesome








    );


    };

    View Slide

  125. Erik Rasmussen – @erikras
    React Solid
    class prop
    export const Table = ()
    =>
    {


    return (








    React


    Awesome








    Solid


    Also Awesome








    );


    };
    export const Table = ()
    =>
    {


    return (








    React


    Awesome








    Solid


    Also Awesome








    );


    };

    View Slide

  126. Erik Rasmussen – @erikras
    classList prop

    View Slide

  127. Erik Rasmussen – @erikras
    React Solid
    classList prop
    export const Item = (props)
    =>
    {


    return (




    className={`item ${


    props.selected ? "selected" : ""


    }`}


    >


    {props.item.name}





    );


    };
    🤮

    View Slide

  128. Erik Rasmussen – @erikras
    React Solid
    classList prop
    import cx from "classnames";


    export const Item = (props)
    =>
    {


    return (




    className={cx("item", {


    selected: props.selected,


    })}


    >


    {props.item.name}





    );


    };

    View Slide

  129. Erik Rasmussen – @erikras
    React Solid
    classList prop
    import cx from "classnames";


    export const Item = (props)
    =>
    {


    return (




    className={cx("item", {


    selected: props.selected,


    })}


    >


    {props.item.name}





    );


    };

    View Slide

  130. Erik Rasmussen – @erikras
    React Solid
    classList prop
    import cx from "classnames";


    export const Item = (props)
    =>
    {


    return (




    className={cx("item", {


    selected: props.selected,


    })}


    >


    {props.item.name}





    );


    };

    View Slide

  131. Erik Rasmussen – @erikras
    React Solid
    classList prop
    import cx from "classnames";


    export const Item = (props)
    =>
    {


    return (




    className={cx("item", {


    selected: props.selected,


    })}


    >


    {props.item.name}





    );


    };

    View Slide

  132. Erik Rasmussen – @erikras
    React Solid
    classList prop
    import cx from "classnames";


    export const Item = (props)
    =>
    {


    return (




    className={cx("item", {


    selected: props.selected,


    })}


    >


    {props.item.name}





    );


    };
    export const Item = (props)
    =>
    {


    return (




    class="item"


    classList={{


    selected: props.selected,


    }}


    >


    {props.item.name}





    );


    };

    View Slide

  133. Erik Rasmussen – @erikras
    React Solid
    classList prop
    export const Item = (props)
    =>
    {


    return (




    className={`item ${


    props.selected ? "selected" : ""


    }`}


    >


    {props.item.name}





    );


    };
    export const Item = (props)
    =>
    {


    return (




    class="item"


    classList={{


    selected: props.selected,


    }}


    >


    {props.item.name}





    );


    };
    🤮 😎

    View Slide

  134. Erik Rasmussen – @erikras
    Lifecycle Methods

    View Slide

  135. Erik Rasmussen – @erikras
    React Solid
    Lifecycle Methods
    export const MyComponent = (props)
    =>
    {


    useEffect(()
    =>
    {


    console.log("MyComponent mounted");


    return ()
    =>
    {


    console.log("MyComponent unmounted");


    };


    });


    return Hello, {props.name}!;


    };

    View Slide

  136. Erik Rasmussen – @erikras
    React Solid
    Lifecycle Methods
    export const MyComponent = (props)
    =>
    {


    useEffect(()
    =>
    {


    console.log("MyComponent mounted");


    return ()
    =>
    {


    console.log("MyComponent unmounted");


    };


    }, []);


    return Hello, {props.name}!;


    };
    🙄

    View Slide

  137. Erik Rasmussen – @erikras
    React Solid
    Lifecycle Methods
    export const MyComponent = (props)
    =>
    {


    useEffect(()
    =>
    {


    console.log("MyComponent mounted");


    return ()
    =>
    {


    console.log("MyComponent unmounted");


    };


    }, []);


    return Hello, {props.name}!;


    };
    export const MyComponent = (props)
    =>
    {


    return Hello, {props.name}!;


    };


    View Slide

  138. Erik Rasmussen – @erikras
    React Solid
    Lifecycle Methods
    export const MyComponent = (props)
    =>
    {


    useEffect(()
    =>
    {


    console.log("MyComponent mounted");


    return ()
    =>
    {


    console.log("MyComponent unmounted");


    };


    }, []);


    return Hello, {props.name}!;


    };
    export const MyComponent = (props)
    =>
    {


    onMount(()
    =>
    {


    console.log("MyComponent mounted");


    });


    return (


    Hello, {props.name}!


    );


    };

    View Slide

  139. Erik Rasmussen – @erikras
    React Solid
    Lifecycle Methods
    export const MyComponent = (props)
    =>
    {


    useEffect(()
    =>
    {


    console.log("MyComponent mounted");


    return ()
    =>
    {


    console.log("MyComponent unmounted");


    };


    }, []);


    return Hello, {props.name}!;


    };
    export const MyComponent = (props)
    =>
    {


    onMount(()
    =>
    {


    console.log("MyComponent mounted");


    });


    onCleanup(()
    =>
    {


    console.log("MyComponent unmounted");


    });


    return (


    Hello, {props.name}!


    );


    };
    FOOTGUN #2:


    The component function is


    only called once!
    NO DEPENDENCY ARRAY NEEDED!!

    View Slide

  140. Erik Rasmussen – @erikras
    ⚡Lightning Round⚡

    View Slide

  141. Erik Rasmussen – @erikras
    • Context API with createContext()

    • Lazy components

    • Suspense

    • useQuery-like Resources with useResource()

    • immer-like mutation API with produce()


    • Next.js-like application framework called SolidStart

    • Routing, SSR, SSG, etc.
    Solid
    Familiar

    View Slide

  142. Erik Rasmussen – @erikras
    • Nested Reactivity with createStore()

    • Batched updates with batch()

    • Directives with use: props

    • Google "solid
    fi
    nal form"
    Solid
    Less Familiar
    ;

    View Slide

  143. Erik Rasmussen – @erikras
    Footgun Recap

    View Slide

  144. Erik Rasmussen – @erikras
    Footgun Recap
    1. Signal values are getter functions!

    2. The Component function is called only once!

    3. Only call signal getters in JSX (or other derived signals).

    Never call getter before return.

    4. Never destructure props!

    5. The Component function is called only once!

    6. The Component function is called only once!

    {value}


    {value()}


    View Slide

  145. Erik Rasmussen – @erikras
    Performance

    View Slide

  146. Erik Rasmussen – @erikras
    React Solid
    React's kryptonite is re-rendering.
    – Erik Rasmussen
    @erikras
    React's superpower is re-rendering.

    View Slide

  147. Erik Rasmussen – @erikras
    React Solid
    React's kryptonite is re-rendering.
    – Erik Rasmussen
    @erikras
    React's superpower is re-rendering.

    View Slide

  148. Erik Rasmussen – @erikras
    React Solid
    – Solid
    @solid_js
    What the 🤬 is "re-rendering"?

    View Slide

  149. Erik Rasmussen – @erikras
    React Solid
    The JS Framework Benchmark compares browser performance across a wide range of tests. Lower is better.

    View Slide

  150. Erik Rasmussen – @erikras
    Conclusion

    View Slide

  151. Erik Rasmussen – @erikras
    Conclusion
    Solid
    vs.
    React

    View Slide

  152. Erik Rasmussen
    @erikras
    https://erikras.com
    Thanks!




    View Slide