This post is not another tutorial. The goes here is to have short notes about the react.

Basic Notes

What is it: JavaScript library created by Facebook for buiding user interface. It keeps the DOM in sync with data.

Virtual DOM: in memory DOM manipuated by react before apply the changes in real DOM. ReactDOM manipulate what is created by react and push to screen. It takes the difference between the virtual and real DOM ahd changes only what is necessry (riquired change). Browser-independent DOM system -> improve the performance [Virtual DOM and Internals | Video | Refs and DOM]

Declarative approache: You define the target UI state and react will do the steps to atchive it. React do the instructions to update the DOM

Scripts: React inject the scripts in the build process. The code is transformed to go to the browser. The react optimize the code. The JS projects that doesn't use the build process need to use the script tag with the attribute "type=mode" to make the imports works as expected.

Node: Nodejs is used behind the scenes to the build process. Then npm transform the index.js (which find rootId in index.html and insert the Apps component) to a better js to the browser.

// Create project
$ npx create-react-app myProjectName

// Download the libraries
$ npm install

// Start the project       
$ npm start

Summary: Reacts only care about props (data from the parent component), components, states (internal data), and context (component-wide data). When props, states, etc. change the component, then the function is reexecuted (re-evaluated by react); it does not mean the component is re-rendering the DOM. The real DOM is updated only in the peace, where it needs to be changed based on the differences between the states. It improves performance because all of this is in memory. When a component function is re-evaluated, all the component children are re-loaded as well. It can be lost because the children can make no changes. An optimisation is React.memo, which compares the props they change. It means that React stores the previous values to do the comparison, and it is a cost too, so it is a trade-off. It's necessary to use it in cases where you have many components' children that make it worth it. Trick pioint: when you attribute a method, it is added to the constant every re-execution, then it is considered a change. The comparison happens like using '===', so it's ok to use primitive values. React elements are immutable. [Thinking in React]


Foundation Notes

Components: React is Component-Driven User Interface. It can be Functional Components or Class-based-Components. Now days the best practices is to use Functional Components with JSX. It is CSS + HTML + JS. It is useful to Resusability (DRY - Don't Repeat Yourself) and to Separation of concern (Don't do too many things in one and the same place). .

JSX: It provides a friendly syntax for the components. It is similar to HTML but it is not HTML. It is not compiled to JavaScript. JSX represents object. JSX compiler is Babel. Rules: Return a single root element (try use fragments to avoid deep level of div); Close all the tags; camelCase all most of the things. JSX void injection and XSS attacks (cross-site-scripting). Everything is transformed to string. [Introduction JSX | JSX in Depth]

// Without JSX
const element = React.createElement('div', { className: 'container' }, 'Hello World!!!' );

// With JSX
const element = <div className="container">Hello World</div>;
ReactDOM.createRoot(rootElement).render(element);

Fragments: It is a resource to return or group multiples elements. It's better use fragments instead of "div" tags because It gets executed faster than div tag or DOM elements. It uses less memory to execute. [Fragments]

// Example 1
<React.Fragment><h1>Hello World!</h1></React.Fragment>

// Example 2
<><h1>Hello World!</h1></>

Props: or properties is a single object that represent the attributes passed to the components (or function). It is a communication between the components. "Parent to Child" communication is passing a data property into a component. "Child to Parent" communication is passing a function as a property into a component. It's possible passing JSX as children (component in component). The properties are read-only, immutable. Even is possible change it as object is supose not change it. The attributes must be manipulated by state. For a typecheck can be used PropType. Best practice: Destructuring Props. [Components and Props | Passing Props]

Events | Handling Events: is better practices to use arrow function then bind. React events are named using camelCase, rather than lowercase. With JSX you pass a function as the event handler, rather than a string. Event handlers have access to the React event that triggered the function.

Lifecycle Events to class-based component [Lifecycle - React.Component | Lifecycle Event]:

  • componentDidMount: build in method; when the component was just mounted (was evaluated and rendered) -> eq useEffect(..,[]) without dependences.
  • ComponentDidUpdate: once the component was updated (evaluated and rendered) -> useeffect(…,[someValue]) with dependences
  • componentWillUnmount: called before component is unmounted (removed from DOM) -> useEffect(()=>return {…}},[])

State: represent a component instance on the screen. In other words, if you render the same component twice, each copy will have completely isolated state! [State vs props | State a component Memory]

  • lifting state Up: pass the state to parent and it can pass to the sibling
  • It can be derived or computed state
  • Stateless: no internal state
  • Setting state only changes it for the next render
  • A state variable’s value never changes within a render, even if its event handler’s code is asynchronous.
  • React keeps the state values “fixed” within one render’s event handlers.
  • After hooks (> React 16.8) the react can handle state, can handle lifecycle event (useEffect), can use stateful logic with Custom Hook

Form: It works as usual refreshing the page when it is submmited. However, to let that control with react is used event.preventDefault() method. In React, the data is handled by the components via state. Each fields can be accessed by event.target.name.

Router: It associates a route with a controller action what means that the app go to another component. When use React the back button in the browser not work because the browser's history is not update when change the component. It's necessary to make it works by BrowserRoute [react-router-dom] and NativeRouter[react-router-native]. Here are some examples how to use it: Example 1, Example 2, Example 3.

npm install -D react-router-dom

Absolute vs Reelative path: In the absolute path (e.g: '/product') the path will be added after the domain name and all the other parts of the path is hidden. In the Relative path (e.g: 'product') add the path after the current active route path.

// Absolute Path: http://mydomain/product
{
    path: "/root",
    ...
    children: [
        {path: "/product", element: <Product />},
    ],

}

// Relative Path: http://mydomain/root/product
{
    path: "/root",
    ...
    children: [
        {path: "product", element: <Product />},
    ],

}

// Avoid Relative PATH in imports
// Relative path
import MyModule from '../../../components/MyModule';
// Absolute Pathh
import MyModule from 'Components/MyModule';

Outlet: used in parent route elements to render their child route elements. This allows nested UI to show up when child routes are rendered

NavLink: is a special kind of that knows whether or not it is "active" or "pending".


Hook Notes

  • Best practices: funcion components with hook; avoid class components
  • Only call hooks at the top level
  • Only call hooks from React Functions
  • When Customize: it is the practices of extract component logic into reusable functions. It can be necessary when you have one or multiple React hooks that will be used at multiple locations in a code
  • Lifting State Up: lift it up to their closest shared ancestor, and pass it down as props to both of them
  • Stateless vs Stateful
  • Hooks API Reference
  • Router Hooks
  • react@18 - hooks

  • Basic Hooks

    useState: declare a state variable that will track some data in the application. It has the current state and a function to update it. The attribute has to be updated by the 'set' method, not directly. For performance, react can update multiple sets in a single update.

    // Declare using Array Destructing
    const [myAttribute, setMyAttribute] = React.useState();
    // set new value
    setMyAttribute('vaue');
    // setting based on prior state
    setTime((previousValue) => previousValue + 'newValue');
    
    // Multiple State Variable
    const [state, setState] = useState({ att1: 0, att2: 0, att3: 0 });
    setState(state => ({ ...state, att2: 10 }));

    useEffect: Manage side-effect (e.g.: data fetching, subscription, logging). The funcion inside this hook is executed after renderer the screen (DOM updates). The function can run only after the first render or after a dependency be changed. If it returns something, then it is necessary to use cleanup, which will be executed when the component is unmounted (executed next time befor re-run | clean up the old effect). When using async function there is a trick point. It returns a Promise, and to make it works is necessary to let the function execute directly without the return or async/await words. Then the return is undefined and is not necessary a cleanup function.

    // 1
    useEffect(loadData, []);
    // 2
    useEffect(loadData, [dependency]);

    useCallback: save the method in some place in react internal's storage and always will use the same method when the component function execute. Trick point: variables from outside is storage from react and will not change, then it is necessary have the dependecy declared. That's a point to thing if is better let create a new function.

    useContext: manipulate the context. It manages state globally. The context is the data that the application will need in many components and will be better to use inside the context and pass throught the components via props or functions.

    useReducer: alternative to manipulate complex state. You can have a new state based on the previous states.

    // Definition
    const myReducer = (currentState, action) => {
      if (action.type === 'A') {
        return { value: action.val, isValid: action.val.includes('+') };
      } else if (action.type === 'B') {
        return [...currentState, action.val];
      }
      return { value: '', isValid: false };
    };
    
    // initial state
    const [myState, dispatchMyState] = useReducer(myReducer, { value: '', isValid: null, });
    
    // funtion
    const myChangeHandler = (event) => {
      dispatchMyState({type: 'A', val: event.target.value});
    };
    
    // Element
    <input value={myState.value}  onChange={myChangeHandler} />

    useRef: lets you reference a value that’s not needed for rendering. With it, the value is not reset every render, it not trigger re-render. It can manipulate a value or a DOM element.

    // Value
    let ref = useRef(0);
    ref.current = ref.current * 2;
    
    // DOM element
    let inputRef = useRef(null);
    <input ref={inputRef} />;
    inputRef.current.focus()

    useState x useReducer

    • useState: the main state management tool, great independent pieces of state/data, great if state updates are easy and limited to a few kinds of updates
    • useReducer: great if you neeed more power, should be considered if you have related pieces of state/data, can be helpful if you have more complex state updates

    useMemo: cache the result of a calculation between re-renders. It optimize the app.


    Router Hooks

    useParam: get the key-value pair in the Route path.

    useNavigation: get al the information you need to know about a page navigation.

    useSubmit: let the app submit the form instead of the user.

    useFecher: do actions and loadres without navigation.

    useRouterLoaderData: makes the data at any currently rendered route available anywhere in the tree.

    useRoutes: similar of use the element Routes.


    Advanced Concepts

    Portals: an alternative to render an element in some other DOM node outside of the DOM hierarchy. It means move a fragment using DOM. Bellow you can see a fragment of code with an example. The complete example you can see here

    // Your component
    ...
    {ReactDOM.createPortal(
        <MyComponent />,
        document.getElementById('overlay-root')
        )}
    ...
    
    // index.html
    ...
    <div id="overlay-root"></div>
    <div id="root"></div>
    ...

    Wrapper: It is an alternative instead to use divs or fragment. IT's a way to put the elements inside a container, providing a default structure to display the children. It can works like a template. [Example 1 | Example 2]

    Lazy loading: load the component only when is rendered for the first time.

    const myComponent = React.lazy(() => import('./myComponent '));

    Authentication:

  • server-side sessions: (1) store unique identifier on server, send same identifier to client; (2) client sends identifier along with requests to protected resources
  • authentication tokens: (1) create(but not store) permission token on server, send token to client (2) client sends token along with requests to protected resources
  • Tests:

  • Jest: tool for running tests and assrting the results
  • React Testing Library: tool for simulating (rendering) the react app/ components

  • References