• Use absolute path
    1. Create jsconfig.json file in the root folder
    2. Write there
        {
          "compilerOptions": {
            "baseUrl": "src"
          },
          "include": ["src"]
        }        
                
    3. Example of use

      Put App.js under components folder

      Import as

      import App from 'components/App';



  • For Deployment
    • In package.json
        "homepage": "/projects/211/projName/",
                
    • In index.html
        <base href="%PUBLIC_URL%/">           
                
    • In App.js
        import { BrowserRouter as Router } from 'react-router-dom';
      
        function App() {
          return (
            <Router basename={process.env.PUBLIC_URL}>  {/* Basename is used due to deployment in subfolder on my web site */}
            ...
            </Router>
          );
        }
      

  • ?? null conditional operator
      const initialValues = selectedEvent ?? { 
        title: "",
        date: "",
      };
    

  • Filter multiple conditions
      userResources.filter(({ id, uniqueId }) => id !== payload.resourceId && uniqueId !== payload.uniqueId)
    

  • const onSubmit = () => {
      selectedEvent
          ? updateEvent({ ...selectedEvent, ...values }) // override previous values
          : createEvent({
              ...values,
              id: cuid(),
              hostedBy: "Bob",
              attendees: [],
              hostPhotoURL: "./assets/user.png",
            });
      };
    

  • Show Navbar on the inner pages only
          <Router>      
          <Route exact path='/' component={Homepage} /> {/* don't show NavBar here */}
          <Route
            path={"/(.+)"} // path other than '/'
            render={() => (
              <>
                <NavBar setFormOpen={onFormOpen} selectEvent={handleSelectEvent} />
                <Container className='main'>
                  <Route exact path='/events' component={EventDashboard} />
                  <Route path='/events/:id' component={EventDetailedPage} />
                </Container>
              </>
            )}
          />
        </Router>
    
    See Re-events project #267, #268, #269

  • React Router
     
      import {useHistory} from 'react-router-dom';
    
      const history = useHistory();
    
      const onSubmit = () => {
        ...
        history.push("/account");
      };
    
    

      
      
     const LoginForm = () => { 
       const mode = new URLSearchParams(window.location.search).get("mode");
       const actionCode = new URLSearchParams(window.location.search).get("oobCode");
     }
    
     https://mySite.app/login?mode=action&oobCode=code
    

  • useEffect()
    • useEffect() runs after every component render:

          useEffect(() => {
            document.title = `You clicked ${count} times`;
          });
      
    • useEffect() runs only if count was changed

          useEffect(() => {
            document.title = `You clicked ${count} times`;
          }, [count]);
      

    • Run once useEffect() - run only on initial render
          useEffect(() => {
            ...
          // eslint-disable-next-line
          }, []);
      

    • useEffect() with cleanup
          useEffect(() => {
            ...
      
            // Cleanup code
            return () => {
              window.removeEventListener('mousemove', logMousePosition);
            }
          }, []);
      

    • prev
        const [count, setCount] = useState(0)
      
        const tick = () => {
          setCount(count + 1)
        }
        useEffect(() => {
          const interval = setInterval(tick, 1000)
          return () => {
            clearInterval(interval)
          }
        }, [count])
      

      Same as

        const [count, setCount] = useState(0)
      
        const tick = () => {
          setCount(prevCount => prevCount  + 1)
        }
      
        useEffect(() => {
          const interval = setInterval(tick, 1000)
      
          // Cleanup
          return () => {
            clearInterval(interval)
            }
        }, [])  
      

    • Function inside UseEffect()
        useEffect(() => {
          function doSomething() {
            console.log(someProp);
          }
      
          doSomething();
          const interval = setInterval(tick, 1000)
      
          // Cleanup
          return () => {
            clearInterval(interval)
            }
        }, [someProp]) 
      

    • Async function inside useEffect
          useEffect(() => {
            async function fetchData() {
              const url = `https://api.github.com/users`; 
              setLoading(true);
              const response = await axios.get(url)
              setUsers(response.data)
              setLoading(false);  
            }
            
            fetchData();
        }, []);
      

    • Async function outside useEffect
        import { useState, useEffect } from 'react';
        import axios from 'axios';
        import PostItem from './PostItem';
      
        const PostList = () => {
          const [posts, setPosts] = useState({});
          // Object.values(posts) is an array of post objects. !!!!!
      
          const fetchPosts = async () => {
            const rootUrl = process.env.REACT_APP_POSTS_BASE_URL;
      
            const res = await axios.get(`${rootUrl}/posts`);
      
            setPosts(res.data);
          };
      
          useEffect(() => {
            fetchPosts();
          }, []);
      
          return (
            <div className="d-flex flex-row flex-wrap justify-content-between">
                {Object.values(posts).map((post) => (
                  <PostItem key={post.id} post={post} />
                ))}        
            </div>
          );
        };
      
        export default PostList;
      

    • Multiple useEffect calls in the same component
            useEffect(() => {
            }
      
            useEffect(() => {
            }
      

  • Scroll to top
    import { useEffect } from "react";
    import { useLocation } from "react-router-dom";
    
    export default function ScrollToTop() {
      const { pathname } = useLocation();
    
      useEffect(() => {
        window.scrollTo(0, 0);
      }, [pathname]);
    
      return null;
    }
    
      <Router>
        <ScrollToTop />
      </Router>
    
    See project #268 Re-vents

  • Scripts
    "scripts": {
       "build": "cross-env GENERATE_SOURCEMAP=false react-scripts build",  
    }