1. Use Yup to validate email input

    Yup.string().email("Invalid email address").required("Required")
    

    <aside>

    Yup needs to know the type of value (string) and then chain the different validation rules with their associated error message to show.

    </aside>

  2. What is the output?

    1. You write “Wash the car” in the first ToDo input

    2. You write “Buy bumper stickers” in the second ToDo input

    3. You click the button to reverse the order

    const ToDo = props => (
      <tr>
        <td>
          <label>{props.id}</label>
        </td>
        <td>
          <input />
        </td>
        <td>
          <label>{props.createdAt}</label>
        </td>
      </tr>
    );
    
    function App() {
      const [todos, setTodos] = useState([
        {
          id: 'todo1',
          createdAt: '18:00',
        }, 
        {
          id: 'todo2',
          createdAt: '20:30',
        }
      ]);
    
      const reverseOrder = () => {
        // Reverse is a mutative operation, need to create a new array first
        setTodos([...todos].reverse());
      };
    
      return (
        <div>
          <button onClick={reverseOrder}>Reverse</button>
          {todos.map((todo, index) => (
            <ToDo key={index} id={todo.id} createdAt={todo.createdAt} />
          ))}
        </div>
      );
    }
    

    <aside>

    Before clicking Reverse

    After clicking Reverse

    So the UI looks like this:

    when reversing the order React understands they are still the same nodes with key=1 and key=2, so it will preserve their internal state (input value). Since the props are different though, it will just update the node with the new prop values.

  3. Errors in ThemeProvider

    import{ createContext, useContext, useState} from"react";
    
    const ThemeContext = createContext(undefined);
    // createContext deault value?
    
    export const ThemeProvider= () => {
      const[theme, setTheme] = useState("light");
    
      return(
        <ThemeContext.Provider
          value={{
            theme,
            toggleTheme: () => setTheme(!theme),
            //toggleTheme: () =>setTheme(theme === "light" ? "dark" : "light")
          }}
        >
        </ThemeContext.Provider>
      );
    };
    

    <aside>

    </aside>

  4. React Elements

    <aside>

    </aside>

    True or False: A tree of elements cannot mix and match both components and DOM elements as the type property.

    <aside>

    False → it is false to claim that they cannot be mixed and matched, actually, they can

    </aside>

  5. Submit Button

    const Button = ({ children, ...rest }) => (
      <button onClick={() => console.log("ButtonClick")} {...rest}>
        {children}
      </button>
    );
    
    const withClick = (Component) => {
      const handleClick = () => {
        console.log("WithClick");
      };
    
      return(props) => {
        return<Component {...props} onClick={handleClick} />;
      };
    };
    
    const MyButton = withClick(Button);
    
    export default function App() {
      return <MyButton onClick={() => console.log("AppClick")}>Submit</MyButton>;
    }
    

    True or false: When the user clicks the Submit button, the “WithClick” string will never be output to the console.

    <aside>

    True → "WithClick" will never be logged

    Reason: although withClick defines handleClick that logs "WithClick", that function is only passed down as an onClick prop. The wrapped Button component does not use the passed onClick prop at all; it defines its own onClick handler

    </aside>

    what would be logged into the console when clicking the Submit button that gets rendered on the screen?

    <aside>

    What gets logged when clicking the Submit button:

    due to the order of the spread operator in the different components, the withClick higher Order Component (HOC) takes precedence

    ButtonClick
    

    Why

    Inside Button:

    <button onClick={() =>console.log("ButtonClick")} {...rest}>
    

    What does NOT log

  6. True or False: Using jest and react-testing-library, to assert that a function has been called with some specific arguments, you would need to use the toHaveBeenCalledWith matcher

    <aside>

    True → this is the proper matcher to check the arguments of the function call

    </aside>

    True or False: Using jest and react-testing-library, to assert that a function has been called with some specific arguments, you would need to use the toHaveAttribute matcher.

    <aside>

    False

    </aside>

  7. Valid examples of the render props pattern

    <aside>

    Render props means:

    // no
    <LoginUser renderUser={<p>Mark</p>} /> 
    
    // yes - uses a render type prop that is a function that returns JSX
    <MealProvider render={data => (
      <p>Ingredients: {data.ingredients}</p>
    )} />
    
    // yes - uses a render type prop that is a function that returns JSX 
    // even though the name is not exactly “render”, 
    // explicit variations are also valid
    <Row renderIcon={() => <Icon name="add">}/>
    
  8. You need the below code snippet to run only after the initial render. What updates (if any) do you need to make to the code?

    React.useEffect(()=> {
     console.log('The value of the toggle variable is', toggle)
    }, [])
    

    <aside>

    To run the effect only on the initial render, you need an empty dependency array.

    </aside>

  9. Re-render with useState

    import {useState} from "react";
    
    export default function App() {
      const [restaurantName, setRestaurantName] = useState("Lemon");
    
      function updateRestaurantName() {
        setRestaurantName("Little Lemon");
      };
    
      return (
        <div>
          <h1>{restaurantName}</h1>
          <button onClick={updateRestaurantName}>
            Update restaurant name
          </button>
        </div>
      );
    };
    

    <aside>

    useState is the key reason neither restaurantName nor setRestaurantName is reset between re-renders.

    Why restaurantName is not reset

    const [restaurantName, setRestaurantName] = useState("Lemon");
    

    So even though the component function runs again, restaurantName comes from React’s state store, not from re-executing useState("Lemon").


    Why setRestaurantName is not reset

    React does not recreate a new setter on each render; it reuses the same function tied to that state slot.


    Key conceptual distinction

    useState creates a persistent state slot that survives re-renders, which is why neither value is reset.


    Final summary

  10. Is the following code snippet valid? Why?