React Elements and Components

  1. React elements
    1. A React element is the smallest building block of a React app
    2. React elements are combined into components, which split the UI into independent, reusable pieces
    3. React elements are rendered into a root DOM node
      1. A root DOM node is any DOM node that is managed by React
        <div id="root"></div>
        
      2. ReactDOM.render() renders a React element into a root DOM node
        const element = <h1>Hello, JSX</h1>;
        ReactDOM.render(element, document.getElementById('root'));
        
    4. React elements are immutable, meaning that once the element is created, the element's attributes or children cannot be changed
  2. Components and props
    1. React elements often represent user-defined components (must start with captial letter to avoid confusion with DOM tags)
      const element = <Welcome />;
      
    2. Component attributes are passed to components in an object called props (short for properties)
      // props = {name:"Becky"}
      const element = <Welcome name="Becky" />;
      
    3. Number and boolean props must be specified with {}
      // props = {name:"Becky", count:4, visibible:true}
      const element = <Welcome name="Becky" count={4} visible={true} />;
      
    4. Components can be created in two ways
      1. Function component - The simplest component is a JavaScript function with a props parameter and returns a React element
        function Welcome(props) {
           return <h1>Hello, {props.name}!</h1>;
        }
        
      2. Class component - The equivalent ES6 class extends React.Component and has a render() method that returns a React element; useful for additional functionality like state management (later in notes)
        class Welcome extends React.Component {
           render() {
              return <h1>Hello, {this.props.name}!</h1>;
           }
        }
        
  3. Component of components
    1. Components can use other components in their output
      function Welcome(props) {
      	return <h1>Hello, {props.name}!</h1>;
      }
      
      function App() {
      	return (
      		<div>
      			<Welcome name="Becky" />
      			<Welcome name="Jim" />
      			<Welcome name="Edwardo" />
      		</div>
      	);
      }
      
      ReactDOM.render(
      	<App />,
      	document.getElementById('root')
      );
      
    2. Note that components that return multi-line JSX must use () to surround the JSX, and there must always be one parent element (use <> to create a fragment when no element is wanted)
      function App() {
      	// Wrong! Missing single parent element
      	return (
      		<Welcome name="Becky" />
      		<Welcome name="Jim" />
      		<Welcome name="Edwardo" />
      	);
      }
      
      function App() {
      	// Create a fragment instead 
      	return (
      		<>
      			<Welcome name="Becky" />
      			<Welcome name="Jim" />
      			<Welcome name="Edwardo" />
      		</>
      	);
      }
      
    3. New React apps typically have a single App component at the top and then child components that might each have their own children
    4. Example Comment component has a UserInfo child component, which has an Avatar child component
      function Avatar(props) {
        return (
          <img className="Avatar"
            src={props.user.avatarUrl}
            alt={props.user.name}
          />
        );
      }
      
      function UserInfo(props) {
        return (
          <div className="UserInfo">
            <Avatar user={props.user} />
            <div className="UserInfo-name">
              {props.user.name}
            </div>
          </div>
        );
      }
      
      function Comment(props) {
        return (
          <div className="Comment">
            <UserInfo user={props.author} />
            <div className="Comment-text">
              {props.text}
            </div>
            <div className="Comment-date">
              {formatDate(props.date)}
            </div>
          </div>
        );
      }