JSX and Styling

  1. JSX
    JSX stands for JavaScript XML. It's a syntax extension for JavaScript often used with React to describe what the UI should look like. JSX allows developers to write HTML-like code within JavaScript, making it easier to visualize and write UI components.

    JSX also allows embedding JavaScript expressions within curly braces {}, allowing dynamic content and logic to be incorporated into the UI:

     const name = 'John';
     const element = <h1>Hello, {name}</h1>;
    

    JSX makes the code more readable and easier to write, especially when dealing with complex UI structures.

     import React from 'react';
    
     // Define a functional component using JSX
     const MyComponent = () => {
       return (
         <div>
           <h1>Hello, world!</h1>
           <p>This is a simple React component using JSX.</p>
         </div>
       );
     };
    
     export default MyComponent;
    

    i) We import React at the beginning since JSX gets compiled into React.createElement() calls.
    ii) We define a functional component called MyComponent using arrow function syntax.
    iii) Inside the component function, we return JSX code that represents the UI of the component.
    JSX is not directly executed by the browser. Instead, it's transformed into regular JavaScript by tools like Babel before being executed.
    Here's what happens behind the scenes when you write JSX in a React application,
    i) Parsing
    When you write JSX in your React code, JavaScript engines don't understand it because JSX is not valid JavaScript syntax. Therefore, before execution, JSX needs to be transformed into valid JavaScript.
    ii) Transpilation
    React comes with a tool called Babel, which is a JavaScript compiler. Babel is used to transpile JSX into regular JavaScript. During this process, JSX syntax is converted into React.createElement() function calls.
    For example, this JSX code,

     const element = <h1>Hello, world!</h1>;
    

    gets transformed into,

     const element = React.createElement('h1', null, 'Hello, world!');
    

    This transpiled JavaScript code is what the browser understands and executes.
    iii) Execution
    Once the JSX is transpiled into regular JavaScript, the resulting code is executed by the JavaScript engine in the browser or in a Node.js environment. This code creates a virtual representation of the UI called the Virtual DOM, which is then reconciled with the actual DOM to update the UI efficiently.
    So, in summary, JSX is a syntax extension that makes writing React components easier, but it needs to be transpiled into regular JavaScript before it can be executed by the browser or Node.js.

  2. General rules for JSX
    i) Basic Syntax Rules : Single Root Element
    JSX must have one root element. If you need multiple elements, wrap them in a single parent element like a <div> or a React Fragment (<>).

    ii) Basic Syntax Rules : Self-Closing Tags
    Tags with no children must be self-closed.

    iii) Basic Syntax Rules : JSX Expressions
    Embed JavaScript expressions in JSX using curly braces {}.

     const name = 'John';
     const element = <h1>Hello, {name}!</h1>;
    

    iv) Basic Syntax Rules : Attributes
    Use camelCase for JSX attribute names and HTML-like syntax for attribute values.

    v) Conditional Rendering : Using Ternary Operators

     const isLoggedIn = true;
     return (
       <div>
         {isLoggedIn ? <h1>Welcome back!</h1> : <h1>Please sign in.</h1>}
       </div>
     );
    

    vi) Conditional Rendering : Using Logical && Operator

     const unreadMessages = ['Hello', 'World'];
     return (
       <div>
         {unreadMessages.length > 0 && <h2>You have {unreadMessages.length} unread messages.</h2>}
       </div>
     );
    

    vii) Styling :Inline Styles
    Use an object to define inline styles.

     const divStyle = {
       color: 'blue',
       backgroundColor: 'lightgray',
     };
     return <div style={divStyle}>Hello, world!</div>;
    

    viii) Styling : CSS Classes: Use the className attribute to apply CSS classes.

     return <div className="my-class">Hello, world!</div>;
    

    ix) Lists and Keys : Rendering Lists
    Use the map function to render lists of elements.

     const numbers = [1, 2, 3, 4, 5];
     const listItems = numbers.map((number) =>
       <li key={number.toString()}>{number}</li>
     );
    
     return <ul>{listItems}</ul>;
    

    x) Lists and Keys : Keys
    Assign a unique key prop to each list item.

     const items = ['Apple', 'Banana', 'Cherry'];
     return (
       <ul>
         {items.map((item, index) => (
           <li key={index}>{item}</li>
         ))}
       </ul>
     );
    

    xi) Component Naming : Capitalized Component Names
    Component names should start with a capital letter.

     function Welcome(props) {
       return <h1>Hello, {props.name}</h1>;
     }
     // Usage
     <Welcome name="Sara" />
    

    xii) Event Handling: Event Names
    Use camelCase for event handler names.

     function handleClick() {
       console.log('Button clicked');
     }
     return <button onClick={handleClick}>Click Me</button>;
    
  3. Difference between HTML and JSX
    i) Syntax and Structure
    HTML is a markup language used to structure content on the web.It uses a tag-based syntax and is not embedded within JavaScript.

     <div class="container">
       <h1>Hello, world!</h1>
     </div>
    

    JSX is a syntax extension for JavaScript, specifically designed for React. It allows you to write HTML-like code within JavaScript.

     const element = (
       <div className="container">
         <h1>Hello, world!</h1>
       </div>
     );
    

    ii) JavaScript Integration
    HTML does not support embedding JavaScript directly within its tags, aside from attributes like onclick.

     <button onclick="alert('Clicked!')">Click Me</button>
    

    JSX allows embedding JavaScript expressions within curly braces {}.

     const name = 'John';
     const element = <h1>Hello, {name}!</h1>;
    

    iii) Attributes and Properties
    HTML uses attributes directly, often with hyphenated names.

     <input type="text" maxlength="10" />
    

    JSX uses camelCase for most attributes to match JavaScript's naming conventions. Some HTML attributes are named differently in JSX (e.g., class becomes className, for becomes htmlFor).

     <input type="text" maxLength={10} />
     <div className="container"></div>
    

    iv) Self-Closing Tags
    In HTML Self-closing tags are optional for void elements (elements that do not have closing tags, like <img> or <input>).

     <img src="image.jpg" alt="description">
     <input type="text">
    

    In JSX Self-closing tags are mandatory for elements that don’t have children.

     <img src="image.jpg" alt="description" />
     <input type="text" />
    

    v) Event Handling
    HTML uses lowercase event names and can directly include JavaScript code as string values.

     <button onclick="handleClick()">Click Me</button>
    

    JSX uses camelCase for event handler properties and refers to JavaScript functions.

     function handleClick() {
       alert('Clicked!');
     }
     const button = <button onClick={handleClick}>Click Me</button>;
    

    vi) Expressions and Logic
    HTML itself does not support conditional logic or loops; these need to be handled in JavaScript or templating engines.
    JSX supports embedding JavaScript expressions, allowing you to use conditionals and loops directly.

     const isLoggedIn = true;
     const message = isLoggedIn ? <h1>Welcome back!</h1> : <h1>Please sign in.</h1>;
    
     const numbers = [1, 2, 3, 4, 5];
     const listItems = numbers.map((number) =>
       <li key={number.toString()}>{number}</li>
     );
    
     const list = <ul>{listItems}</ul>;
    
  4. React Fragment
    In React, fragments are a way to group a list of children without adding extra nodes to the DOM. This is particularly useful when you need to return multiple elements from a component's render method but don't want to introduce unnecessary divs or other elements into the DOM structure.
    i) Avoiding Unnecessary Wrapping Elements
    Sometimes adding extra divs for the sake of grouping elements can lead to unwanted styling issues or increased complexity in the DOM structure. Fragments solve this problem by allowing you to group elements without adding additional nodes.
    ii) Improving Performance
    By avoiding extra nodes in the DOM, fragments can help keep the DOM tree lighter, potentially improving performance.
    iii) How to Use React Fragments

     import React from 'react';
    
     function MyComponent() {
       return (
         <React.Fragment>
           <h1>Hello, world!</h1>
           <p>This is a paragraph.</p>
         </React.Fragment>
       );
     }
    
     export default MyComponent;
    
     import React from 'react';
    
     function MyComponent() {
       return (
         <>
           <h1>Hello, world!</h1>
           <p>This is a paragraph.</p>
         </>
       );
     }
    
     export default MyComponent;
    
  5. CSS Styling
    Styling in React can be done using CSS files, inline styles, or CSS-in-JS libraries like styled-components or Emotion. Each approach has its pros and cons, depending on factors like project complexity and personal preference.
    Inline styling in React involves directly applying styles to JSX elements using the style attribute. Here's how you can do it,

     import React from 'react';
    
     function MyComponent() {
       const divStyle = {
         color: 'blue',
         backgroundColor: 'lightgray',
         padding: '10px'
       };
    
       return (
         <div style={divStyle}>
           This is a div with inline styles.
         </div>
       );
     }
    
     export default MyComponent;
    

    In this example, divStyle is an object containing CSS properties and their values. These styles are then applied to the <div> element using the style attribute.
    In React, you can add CSS classes to JSX elements using the className attribute, similar to how you would do it in regular HTML. Here's an example,

     import React from 'react';
     import './styles.css'; // Import your CSS file
    
     function MyComponent() {
       return (
         <div className="container">
           <h1 className="title">Hello, React!</h1>
           <p className="paragraph">This is a paragraph.</p>
         </div>
       );
     }
    
     export default MyComponent;
    

    In this example, the className attribute is used to add classes defined in an external CSS file (styles.css). This approach allows you to separate your styling from your component logic, promoting better organization and maintainability.

  6. CSS styling options
    i) Inline CSS
    inline CSS should be placed in the JSX element itself.
    It should applied by using the style prop.

    Scope of this inline CSS is JSX element only.
    It is based on the CSS only.
    ii) CSS or SASS file
    inline CSS should be placed as an external CSS file.
    It should applied by using the className prop.

    Scope of this CSS is the entire app as it is global CSS.
    It is based on the CSS only.
    iii) CSS modules
    This CSS file should be placed as one external CSS file per component.
    It should applied by using the className prop.

    Scope of this CSS is to that specific component only.
    It is based on the CSS only.
    iv) CSS is JS
    This CSS file should be placed as an external JS file.
    It should applied by using a new separate component.

    Scope of this CSS is to that specific component only.
    It is based on the Javascript only.