Components
Basics
Components are the building blocks of every website built with gg. Every component encapsulates some logic, either in the form of the markup that it returns or it can also abstract some client-side state. (We will touch on state later.) It can be reused in pages or also inside other components, and you can customize the behavior of a single component using typed arguments.
Creating components
To define a component you can use the component method exported from the gg-module. We used it before when creating pages. This method accepts one argument, which has to be a function returning either some markup (possibly by using other components) or a string or nothing at all.
1// Returning some markup 2const Headline = gg.component(() => { 3 return <h1>Hello world</h1>; 4}); 5 6// Returning a string 7const Text = gg.component(() => { 8 return "Hello world"; 9}); 10 11// Returning nothing 12const Nothing = gg.component(() => { 13 return null || undefined; 14});
Note that it's also fine to return a possibly nested array from a component, containing either one of the valid return types.
1// Returning an array 2const TwoHeadlines = gg.component(() => { 3 return [<h1>Hello world</h1>, <h2>And hello gg</h2>]; 4}); 5 6// Returning a nested array 7const Nested = gg.component(() => { 8 return [<h1>Hello world</h1>, [undefined, , "And hello gg", null]]; 9});
Components in JSX
You can use components in JSX like regular HTML elements, that is using opening and closing angle brackets.
1const Headline = gg.component(() => { 2 return <h1>Hello world</h1>; 3}); 4 5const markup = ( 6 <body> 7 <Headline /> 8 </body> 9);
When naming components it is important to start the variable name with an uppercase letter. JSX decides how to transform the thing inside angle brackets based on if the first letter is a capital one or not. For names starting with non-capital letters, which includes all the basic HTML elements, the transpilation behind JSX will create an actual HTML element. For all the others, starting with capital letters, transpiling the JSX will assume that the name refers to a component, resulting in a call to the component function.
Component arguments
Components are designed to be generic building blocks. To be able to return not just one and the same thing, you can pass arguments to components. The component function will be called with an object as the single argument, containing key-value-pairs for the arguments you pass to your component in JSX.
There are two ways to pass arguments to a component. The first way relates to the way you nest elements in HTML. Everything you put between the opening and closing tag of your component will be passed to the component as an argument called children.
For a component that should return a headline, it would be a proper use-case to pass the text that should be inside the headline as children to the Headline component.
1const Headline = gg.component((args) => { 2 return <h1>{args.children}</h1>; 3}); 4 5const markup = <Headline>Hello world</Headline>;
Note that you can pass more than one child to a component. Thus the children argument will always be an array. As we learned in the JSX guide, passing an array into a JSX expression is perfectly fine.
The second way of passing arguments to a component relates to arguments in HTML. You can define a custom set of arguments that you then can pass to the component as attributes in JSX. The gg.component accepts one generic type argument which will define those custom arguments.
We can use this to make our Headline component from before more versatile, passing the headline level as an additional argument via an attribute.
1type Args = { level: "h1" | "h2" }; 2const Headline = gg.component<Args>((args) => { 3 switch (args.level) { 4 case "h1": 5 return <h1>{args.children}</h1>; 6 case "h2": 7 return <h2>{args.children}</h2>; 8 } 9}); 10const markup = <Headline level="h2">Hello world</Headline>;
After we learned how to create HTML elements and how to use components, it's finally time for some style!
Next → CSS