11. Git + JS + React + Typescript
CSS
- When we define a variable on an element, it is available to all of that element's children.
/* Whenever an <em> is used within a paragraph, it'll have a yellow background. */
p {
--highlight-color: yellow;
}
em {
background: var(--highlight-color);
}
/* This variable will be available everywhere, because every element is a descendant of the HTML tag: */
/* :root is a reference to the top-level element. It's equivalent to the html selector. */
html {
--color-red: hsl(0deg 80% 50%);
--color-blue: hsl(270deg 75% 60%);
}
:root {
--color-red: hsl(0deg 80% 50%);
--color-blue: hsl(270deg 75% 60%);
}
/* Both are same */
*,
*::before,
*::after {
box-sizing: border-box;
}
- Custom properties need to start with two dashes. This is what differentiates them from traditional CSS properties.
- They can hold any type of value, not just colors and pixels.
- You can specify a default value if the CSS variable isn't defined: var(--primary-color, pink) will fall back to pink if necessary.
- pseudo-class: targeta a specific state of element, :hover, :active, :first-child, :last-child
- pseudo-element: targets a sub-elements within an element., ::placeholder, ::after, ::before.
: Direct child.
- space: inside.
Git
- Version Control System (VCS)
- Centrialized (CVCS), ex: Subversion, Team Foundation Server
- Distributed (DVCS), ex: Git, Bazaar, Mercurial
- Track History and Work together
git config --global user.name "jugshaurya"
git config --global user.email "shuaryasinghal84@gmail.com"
git config --global core.editor "code --wait"
# open file that has global settings for git stored.
# opens .gitconfig file available @home directory
git config --global -e
# making linux and Mac, don't let add carriage return to Line feed @End of Line(EOL)
git config --global core.autocrlf input # set to "true" for windows to add carriage return to line feed to indicate EOL
# Initializing a repository
git init
# Viewing the status
git status # Full status
git status -s # Short status
# Staging files
git add file1.js # Stages a single file
git add file1.js file2.js # Stages multiple files
git add *.js # Stages with a pattern
git add . # Stages the current directory and all its content
# Committing the staged files
git commit -m “Message” # Commits with a one-line message
git commit # Opens the default editor to type a long message
# Skipping the staging area
git commit -am “Message”
# List files in Staging area / Index
git ls-files
# Removing files
rm file.js # Removes from working directory only
git rm file.js # Removes from working directory and staging area
git rm --cached file.js # Removes from staging area only
# Renaming or moving files
git mv file.js file.txt
# Viewing the staged/unstaged changes
git diff # Shows unstaged changes
git diff --staged # Shows staged changes
git diff --cached # Same as the above
# Making vscode the default diff tool
git config --global diff.tool vscode
git config --global difftool.vscode.cmd "code --wait --diff $LOCAL $REMOTE"
##### Now run them instead of git diff #####
git difftool
git difftool --staged
# Viewing the history
git log # Full history
git log --oneline # Summary
git log --reverse # Lists the commits from the oldest to the newest
# Viewing a commit
git show <COMMIT ID> #Shows the given commit
git show HEAD # Shows the last commit
git show HEAD~2 # Two steps before the last commit => (head-2)th commit
# Unstaging files (undoing git add)
git restore --staged file.js # Copies the last version of file.js from repo to index
# Discarding local changes
git restore file.js# Copies file.js from index to working directory
git restore file1.js file2.js# Restores multiple files in working directory
git restore .# Discards all local changes (except untracked files)
git clean -fd# Removes all untracked files
# Restoring an earlier version of a file
git restore --source=HEAD~2 file.js
Javascript
- High Level, Object Oriented, MultiParadigm Programming Language
- Dynamically Typed
- Prototype-based, object oriented
- Interpreted or Just-in-time Compiled
- Single Threaded
- Garbage Collected
- Has Non-blocking event-Loop concurrency Model.
Questions
One way binding vs two way binding?
How Virtual Dom Actually works?
Builds Single Page Application
Virtual DOM
React is Declarative
React is component based
set of immutable values are passed to the components.(properties flow down; actions flow up.)
Composition and not Inheritance.
Hooks are more restrictive than regular functions. You can only call Hooks at the top level of your components (or other Hooks). If you want to use useState in a condition or a loop, extract a new component and put it there.
React Notes
A JavaScript library for building User Interfaces.
React is Declarative
Composition over Inheritance.
React is just Javascript.
Component-Based.
- Components represent the modularity and reusability of React.
- Components should follow the single responsibility principle(from SOLID Principle) and just "do one thing".
Composition is:
- Function composition is a mathematical concept that allows you to combine two or more functions into a new function.(fog(x) and gof(x))
- React makes use of the power of composition, heavily! React builds up pieces of a UI using components. Let's take a look at some pseudo code for an example. Here are three different components:
<Page>
<article />
<Sidebar />
</Page>Can write directly on codepen
- create a new pen, add react, reactDOM, babel CDN
- jsbin, script tag with text/babel and then write JSX.
<body>
<div id="root"></div>
<script src="https://unpkg.com/react@18.1.0/umd/react.development.js"></script>
<script src="https://unpkg.com/react-dom@18.1.0/umd/react-dom.development.js"></script>
<script src="https://unpkg.com/@babel/standalone@7.12.4/babel.js"></script>
<script type="text/babel">
const children = "Hello World";
const className = "container";
const element = <div className={className}>{children}</div>;
ReactDOM.createRoot(document.getElementById("root")).render(element);
</script>
</body>
<body>
<div id="root"></div>
<script src="https://unpkg.com/react@18.1.0/umd/react.development.js"></script>
<script src="https://unpkg.com/react-dom@18.1.0/umd/react-dom.development.js"></script>
<script src="https://unpkg.com/@babel/standalone@7.12.4/babel.js"></script>
<script type="text/babel">
// This is being used as a component. But it's still not quite awesome yet.
function message({ children }) {
return <div className="message">{children}</div>;
}
const element = (
<div className="container">
{React.createElement(message, { children: "Hello World" })}
{React.createElement(message, { children: "Goodbye World" })}
</div>
);
ReactDOM.createRoot(document.getElementById("root")).render(element);
</script>
</body>
<body>
<div id="root"></div>
<script src="https://unpkg.com/react@18.1.0/umd/react.development.js"></script>
<script src="https://unpkg.com/react-dom@18.1.0/umd/react-dom.development.js"></script>
<script src="https://unpkg.com/@babel/standalone@7.12.4/babel.js"></script>
<script type="text/babel">
// This is being used as a component 🎉
function Message({ children }) {
return <div className="message">{children}</div>;
}
const element = (
<div className="container">
<Message>Hello World</Message>
<Message>Goodbye World</Message>
</div>
);
ReactDOM.createRoot(document.getElementById("root")).render(element);
</script>
</body>
React Alternatives
- Vue
- Angular
- Backbone
- Ember
CRA(create-react-app) (A build Workflow)
- optimizes code
- can use latest javascript features / syntax.
- yarn / npm + webpack bundler + babel transpiler + webpack dev server + hot reloading + many more...
Container / stateful / smart Components
Component / stateless / dumb / presentational Components
Controlled / UnControlled Form Inputs
props
represent "read-only" data that are immutable.state
, represents mutable data that ultimately affects what is rendered on the page. State is managed internally by the component itself and is meant to change over time, commonly due to user input (e.g., clicking on a button on the page).JSX is awesome, but it does need to be transpiled into regular JavaScript before reaching the browser(means during compilation stage). We typically use a transpiler like Babel to accomplish this for us. We can run Babel through a build tool, like Webpack which helps bundle all of our assets (JavaScript files, CSS, images, etc.) for web projects.
To streamline these initial configurations, we can use Facebook's Create React App package to manage all the setup for us! This tool is incredibly helpful to get started in building a React app, as it sets up everything we need with zero configuration! Install Create React App (through the command-line with npm), and then we can walk through what makes it so great.
Yarn is a package manager that's similar to NPM. Yarn was created from the ground up by Facebook to improve on some key aspects that are slow or lacking in NPM.
Facebook's create-react-app is a command-line tool that scaffolds a React application. Using this, there is no need to install or configure module bundlers like Webpack, or transpilers like Babel. These come preconfigured (and hidden) with create-react-app, so you can jump right into building your app!
React encourages us to build applications using composition instead of inheritance.
- we need to extend React.Component, but we never extend it more than once. Instead of extending base components to add more UI or behavior, we compose elements in different ways using nesting and props. You ultimately want your UI components to be independent, focused, and reusable.
In a blog post, written by Facebook they had mentioned that they had never used Inheritance in their React code across thousands of components. This shows how just using Composition can solve code reuse problems in React.
This process of determining what has changed in the previous and new outputs is called Reconciliation.
For all Components, its UI = f(state).
IMP: Functions that are updating the state(let x) in some way must reside in x-state component, not in children or parent.
Type checking a Component's Props with PropTypes
- As we implement additional features into our app, we may soon find ourselves debugging our components more frequently. For example, what if the props that we pass to our components end up being an unintended data type (e.g. an object instead of an array)? PropTypes is a package that lets us define the data type we want to see right from the get-go and warn us during development if the prop that's passed to the component doesn't match what is expected.
To use PropTypes in our app, we need to install
prop-types
from npm or yarn. - or Use Typescript, that does the work for proptypes and does much more.
- As we implement additional features into our app, we may soon find ourselves debugging our components more frequently. For example, what if the props that we pass to our components end up being an unintended data type (e.g. an object instead of an array)? PropTypes is a package that lets us define the data type we want to see right from the get-go and warn us during development if the prop that's passed to the component doesn't match what is expected.
To use PropTypes in our app, we need to install
Lazy Initilizers are the function passed to useState() and useReducer().
Hooks
Hooks flow
useState
- use of Lazy Initializers
useEffect
useRef
- A ref is an object that stays consistent between renders of your React component. It has a current property on it which can be updated to any value at any time. In the case of interacting with DOM nodes, you can pass a ref to a React element and React will set the current property to the DOM node that's rendered.
useReducer
- use of Lazy Initializers
useContext
useCallback
useDebugValue
useDeferredValue
useId
useImperativeHandle
useInsertionEffect
useLayoutEffect
useMemo
useSyncExternalStore
useTransition
Custom Hooks
- Just the functions that use hooks inside them.
- always should start with
use
.
Controlled Components Recap
- Controlled components refer to components that render a form, but the "source of truth" for that form state lives inside of the component state rather than inside of the DOM.
The benefits of Controlled Components are:
- instant input validation
- conditionally disable/enable buttons
- enforce input formats
- In our ListContacts component, not only does the component render a form, but it also controls what happens in that form based on user input. In this case, event handlers update the component's state with the user's search query. And as we've learned: any changes to React state will cause a re-render on the page, effectively displaying our live search results.
- Putting it All Into Perspective When it comes to keeping track of data in your app, think about what will be done with that data, and what that data will look like as your user interfaces with your app. If you want your component to store mutable local data, consider using state to hold this information. Many times, it is state that will be used to manage controlled form elements in your components.
- On the other hand, if some information isn't expected to change over time, and is generally designed to be "read-only" throughout your app, consider using props instead. Both state and props will generally be in the form of an object, and changes in either will trigger a re-render of the component, but they each play very different roles in your app.
- render() is only used for displaying content, we put the code that should handle things like Ajax requests in what React calls lifecycle events.
Lifecycle Events
Lifecycle events are specially named methods in a component. These methods are automatically bound to the component instance, and React will call these methods naturally at certain times during the life of a component. There are a number of different lifecycle events, but here are the most commonly used ones.
componentDidMount()
invoked immediately after the component is inserted into the DOM componentWillUnmount()
invoked immediately before a component is removed from the DOM getDerivedStateFromProps()
invoked after a component is instantiated as well as when it receives brand new props
To use one of these, you'd just create a method in your component with the name and React will call it. It's an easy way to hook into different parts of the lifecycle of React components.
The lifecycle event that we'll be looking at (and will be using a lot in our app!) is the componentDidMount() lifecycle event.
You'll sometimes see shouldComponentUpdate() in React apps as well. It returns true by default. This means that whenever a component's state (or its parent's state) is updated, the component re-renders.
The React documentation provides the following guidance for using this lifecycle event:
- The default behavior is to re-render on every state change, and in the vast majority of cases you should rely on the default behavior.
- Do not rely on it to “prevent” a rendering, as this can lead to bugs.
- Consider using the built-in PureComponent instead of writing shouldComponentUpdate() by hand. We do not recommend doing deep equality checks or using JSON.stringify() in shouldComponentUpdate(). It is very inefficient and will harm performance.
Now, there are a number of different lifecycle events.
They will run at different points, but we can break them down into three distinct categories:
1. Adding to the DOM
The following lifecycle events will be called in order when a component is being added to the DOM:
constructor();
getDerivedStateFromProps();
render();
componentDidMount();
⚠️componentWillMount() has been deprecated. ⚠️ As of React 16.3, componentWillMount() has been replaced with UNSAFE_componentWillMount(). Only UNSAFE_componentWillMount() will work starting with React 17.0. UNSAFE_componentWillMount() is now considered to be a legacy method and should not be used in new code.
2. Re-rendering
The following lifecycle events will be called in order when a component is re-rendered to the DOM:
getDerivedStateFromProps()
shouldComponentUpdate()
render()
getSnapshotBeforeUpdate()(specific use cases)
componentDidUpdate()
⚠️componentWillReceiveProps() and componentWillUpdate() have been deprecated. ⚠️ As of React 16.3, they have been replaced with UNSAFE_componentWillUpdate() and UNSAFE_componentWillReceiveProps(). Only UNSAFE_componentWillUpdate() and UNSAFE_componentWillReceiveProps() will work starting with React 17.0. UNSAFE_componentWillUpdate() and UNSAFE_componentWillReceiveProps() are now considered to be legacy methods and should not be used in new code.
3. Removing from the DOM
This lifecycle event is called when a component is being removed from the DOM:
componentWillUnmount();
Footer
Single-Page Apps
Single-page applications can work in different ways. One way a single-page app loads is by downloading the entire site's contents all at once. This way, when you're navigating around on the site, everything is already available to the browser, and it doesn't need to refresh the page. Another way single-page apps work is by downloading everything that's needed to render the page the user requested. Then when the user navigates to a new page, asynchronous JavaScript requests are made for just the content that was requested.
Another key factor in a good single-page app is that the URL controls the page content. Single-page applications are highly interactive, and users want to be able to get back to a certain state using just the URL. Why is this important? Bookmarkability! (pretty sure that's not a word...yet) When you bookmark a site, that bookmark is only a URL, it doesn't record the state of that page.
React Router
React Router turns React projects into single-page applications. It does this by providing a number of specialized components that manage the creation of links, manage the app's URL, provide transitions when navigating between different URL locations, and so much more.
According to the React Router website:
React Router is a collection of navigational components that composes declaratively with your application.
npm install --save react-router-dom
<BrowserRouter\/>
going to listen for the changes in url, and make sure correct screen shows up when url changes.
Here is the code straight from the React Router repository.
class BrowserRouter extends React.Component {
static propTypes = {
basename: PropTypes.string,
forceRefresh: PropTypes.bool,
getUserConfirmation: PropTypes.func,
keyLength: PropTypes.number,
children: PropTypes.node,
};
history = createHistory(this.props);
render() {
return <Router history={this.history} children=this.props.children} />;
}
}When you use BrowserRouter, what you're really doing is rendering a Router component and passing it a history prop. Wait, what is history? history comes from the history library (also built by React Training). The whole purpose of this library is it abstracts away the differences in various environments and provides a minimal API that lets you manage the history stack, navigate, confirm navigation, and persist state between sessions.
So in a nutshell, when you use BrowserRouter, you're creating a history object which will listen to changes in the URL and make sure your app is made aware of those changes.
Link is a straightforward way to provide declarative, accessible navigation around your application. By passing a to property to the Link component, you tell your app which path to route to.
<Link to="/about">About</Link>
If you're experienced with routing on the web, you'll know that sometimes our links need to be a little more complex than just a string. For example, you can pass along query parameters or link to specific parts of a page. What if you wanted to pass state to the new route? To account for these scenarios, instead of passing a string to Links to prop, you can pass it an object like this,
<Link
to={{
pathname: "/courses",
search: "?sort=name",
hash: "#the-hash",
state: { fromDashboard: true },
}}
>
Courses
</Link>with a Route component if you want to be able to pass props to a specific component that the router is going to render, you'll need to use Route’s render prop. As you saw, render puts you in charge of rendering the component which in turn allows you to pass any props to the rendered component as you'd like.
<Route to="/" component={Alpha} />
<Route to="/" render={(props) => <Alpha {...props} />} />In summary, the Route component is a critical piece of building an application with React Router because it's the component which is going to decide which components are rendered based on the current URL path.
React Native
Joy of React
A growth mindset is the belief that our brains are elastic, that we become smarter through practice, and that failure is the fastest way to learn. This mindset is a superpower for developers.
Productive Failure
There are two exceptions to the "camelCasing" of attributes: data attributes and ARIA attributes.
Data attributes aren't used that often in React, but they can be helpful for labelling elements for automated testing.
ARIA attributes are used by assistive technologies like screen readers to improve the accessibility of our applications.
<div
style={{
width: 200, // Equivalent to `width: 200px`
paddingTop: 8, // Equivalent to `padding-top: 8px`
}}
>
<p
style={{
lineHeight: 20, // Equivalent to `line-height: 20`
}}
>
- https://www.joshwcomeau.com/snippets/react-components/visually-hidden/
- aria-label only works on interactive elements like buttons.
- The clsx function will take each of these arguments and produce a unified string that satisfies the className prop requirements. It'll automatically remove falsy values like false or null.Ultimately, it's not a game-changer, but it can be a handy little utility! It shaves off some of the rough edges of trying to construct the string ourselves.
- Less code means less space for bugs to hide
- updating a state variable is asynchronous. It's a scheduled update. Because state updates are asynchronous, they can be batched.