Every minute you spend in planning saves 10 minutes in execution; this gives you a 1,000 percent Return on Energy!
To login into the project add credentials: email: demo@st6.io , password: demo1234
GraphQL Playground uder https -> star-wars-graphql-playground
- Component
- JSX JavaScriptXML
- Component Re-render Causes
- Presentational Components(Dumb, Skinny)
- Container Components(Smart, Fat)
- What are refs?
- Controlled vs Uncontrolled Form Components
- Lifting the state
- High order components
- Render Props
- Inversion of control
- React Context
create-react-app official page
- Storybook
- Testing React Components
- Git Hooks Husky Lint Stage and Cross Env - Deploying with CI 55min in Video
- List of VS code extensions
- Shallow Render
- Jest Enzyme addon
- browserrl.ist - check supported browsers for the configuration in package.json at browserslist: {production}
- Why hooks were invented and problems they solved
- What are hooks
- Build-in Hooks
- Rules for hooks
- Write you own hook
GrqphQL Introduction Video
- Official tutorial for graphql
- graphql-introduction-graphql
- traditional-rest-graphql
- resources-in-restgraphql
- rest-principals
- what-is-graphql
- graphql-advantages-graphql
- concepts-in-graphql-graphql
- schema-definition-language-sdl
- graphql-language-is-basically-about-selecting-fields-on-objects-graphql
- type-system
- non-nullable-definition
- object-types
- field-arguments
- query-and-mutation-object-types
- scalar-types
- enumeration-types
- interfaces
- query-arguments
- fields-aliases
- fragments-similar-to-spread-operator-in-js
- variables
- directives
- typename-field-it-is-metatype-data
- mutations
- retrospection-tool-for-extracting-information-about-our-schema
- Main building blocks: - Reusability and Isolation
- Component props: - External data coming from parent to child
- Immutable Accessed from single object argument for functional components
-
Combines markup with logic. JavaScript Expressions -> {}
-
produce React elements
-
React Elements
-
smallest building blocks
-
plain object made with logic,Ex: const name="pax" React.createElemetn('div', {className: 'element'}, 'I am', name)
-
in the Virtual DOM this React element is only a plain object => { type: 'div', props: { className: 'element', children: 'Some content pax' } }
-
produces React elements JSX in depth official documentation
- Props Change
- State Change
- Context Change*
- How things Look
- Usually renders **host(html elements in web, native elements in React Native(View, Text)**components
- No external dependencies
- Lack of knowledge about data mutations and loading
- They are Pure functions(when using functional components)
- No state
- How things Work
- Usually no **host(html elements in web, native elements in React Native(View, Text)**components
- Linked to external providers(redux-connect, appolo-qraphql, etc.)
- Serves as data and behaviorproviders
- Usually stateful
- Complex logic is here
- Separation of concerns
- Better reusability
- Enforces Good Practices
- Makes Styling Easier
- The outcome will be: Small components, Easy to tests, Easy to reuse
- Imperatively control child's behavior
- Child can be either DOM element or React Component
- Used for accessing child component instance throughout the component lifecycle
- Component should be mounted, to ref(instance of the element)
-
With functional components useRef()
-
Pass the ref instance to an element ref attribute in render
-
Control the rendered element via the ref instance reference
-
Depending on the child type ref instance receives different object as current property
-
HTML element - the instance of the underlying DOM element
-
React Component - the instance of the mounted component Refs and the DOM
Article with examples: Controlled vs Uncontrolled
- You don't have access to hooks beside componentDidMount()
- You should taka care of the internal state, instead of allowing React to do this for you
- Keep internal state
- Uncontrolled
- current value is pulled from the components using ref
- Defaults to HTML Form elements behavior
- input, textarea, select
- React doesn't recommend this pattern but it's useful when developers only care about the final state rather than the intermediate state of the component
- Definition - In HTML, form elements such as input , textarea , and select typically maintain their own state and update it based on user input. ... An input form element whose value is controlled by React in this way is called a "controlled component".
- React state (redux) becomes single source of truth
- Data is pushed to components using a prop (value/checked)
- React component controls the behavior of the rendered form onUserInput**
- Input components whose value is controlled by React are called controlled components
- one-time value retrieval (e.g. on submit) YES/YES
- validating on submit YES/YES
- instant field validation NO/YES
- conditionally disabling submit button NO/YES
- enforcing input format NO/YES
- several inputs for one piece of data NO/YES
- dynamic inputs NO/YES
- use uncontrolled componentns when there is no other way(ex: call native DOM function like focus() on input element)
Article: Lifting the state Official Documentation
- Each changeable data should have single source of truth
- Prefer top-down data flow instead of syncing state between interdependent components
- Initially, place the state as close as possible to the component in interest
- Lift the state up to the closest common ancestor for components requiring the same data
- Anything derivable/reducible from props or state, shouldn’t be stored in the state.
- Abstract Same Pattern Logics to be reused by Components
- Encapsulate Behaviors
Introduction to higher order components (HOC) in React Official Documentation: higher order components
- Inspired by higher-order functions
- Takes component as an argument and returns new component
- Composes the input component by wrapping it in a container component
- Doesn’t modify the input component
- Don’t compose within the render method
- Static members should be hoisted
- Refs aren’t passed through
- Name collisions
- Indirections
- Render Prop refers to a technique for sharing code between React components using a prop whose value is a function1
- Encapsulates Behavior
- Better Reusability
- Mind when using with PureComponent Render Props official documentation
- see ContainerComponent implementation in Training/ReactAdvanced/Component/component
- Higher-level components become more complicated
- Might cause lower-level component to be more flexible than wanted
- Having multiple children needing same props
- Same data necessary to different components at different nesting levels of the tree
- Passing data all the way from top to bottom
- Some intermediate components don’t care about the data
- Redundancy
- Context provides a way to pass data through the component tree without having to pass props down manually at every level Broadcast data and changes to all interested components down the tree.
- Accessing current locale
- Getting a theme styles
- Caching data Context API official documentation When context replace redux
Link to react-scripts with all commands: start, build, eject..
- yarn - creating the app with yarn
- yarn global add create-react-app
- yarn create react-app swapp
- npm - creating the app with npm
- npm init react-app swapp
- npx - creating the app with npx
- npx create-react-app swapp
- yarn start
- npm start
- yarn test
- npm test
- yarn build
- yarn eject or npm eject
- Irreversible
- Reasons:
- Manage the Build
- Missing Features
- Curiosity
- yarn upgrade react-script --latest
- Via .babelrc { "presets": ["@babel/preset-react"] }
- Webpack
- Eslint
- Styles and Assets
- Environment Variables
- Progressive Web Apps
- Jest
Webpack official sait for webpack
- Builds Dependency Module Graph
- Picks up non-JS files via Loaders
- Bundle Optimizations via Plugins
- Code Splitting
Eslint official sait for Eslint
- Maintain code consistency
- Enforces Good Practices
- Simplifies PR Reviews
- eslint-plugin-react
- Webpack extends the concept of import
- Importing images, fonts, svgs. etc
- Importing Styles
- Import CSS or SASS* files as dependency
- Import CSS or SASS* modules
- [name].module.{css,scss} - Adding a CSS Modules Stylesheet
- Style scoping via unique classnames
- via Shell or .env
- Reserved Environment Variables (e.g. PORT)
- Custom Environment Variables
- Used for custom purposes (e.g. setting the backend server url)
- Must be prefixed with REACT_APP* (e.g. REACT_APP_BE_URL)
- Web Apps having specific set of characters:
- Progressive
- Responsive
- Connectivity independent
- App-like
- Faster after initial loading
- Progressive by Default*
- Service Worker
- Pin the Node.js version
- Opinionated Formatter
- Pre-commit hooks
- CI/CD
- Limits Hard to Reproduce Issues
- Ensures Node.js version consistency
- nvm, nvm-windows, nodist
Node Version Manager (nvm) nvm git repo
- Install nvm
- echo [desired version] >> .nvmrc
- call "nvm use" - where the file is located folder
- or set up automatic nvm use call
- locking-down-a-project-to-a-specific-node-version-using-nvmrc-and-or-engines
- Resolves visual esthetics arguments
- Uses cosmiconfig link
- Create format script In package.json "prettier": { "trailingComma": "all", "tabWith": 2, "semi": true, "singleQuote": true }
- Format with prettier all files that are listed, ex: {js,json, css, scss} "scripts": { ... "format": "prettier --write "src/*/.{js,json, css, scss}"" }
CI with lint staged and husky pre commit - article
-
npm install --save-dev husky lint-staged cross-env
-
cross-env -cross-env - Run scripts that set and use environment variables across platforms
-
husky - Husky can prevent bad git commit, git push and more dog woof! husky git
-
lint-staged link — Run linters on git staged files, Run linters against staged git files and don't let hankey slip into your code base! prettier git repo
-
in package.json "husky" : { "hooks": { "pre-commit": "cross-env CI=true lint-staged", "pre-push": "npm test" } }
"lint-staged": { "src/*/.js": [ "prettier --write", "eslint --max-warnings=0", "yarn test --bail --findRelatedTests", "git add" ] }
- netlify.toml and the file into the project level with content:
- [build]
- base = "/"
- publish = "/build/"
- command = "yarn ci && yarn build"
- Always use Pull/Merge Requests
- Run CI Build on each PR
- Deploy Automatically the master branch
Storybook is an open source tool for developing UI components in isolation
- Build Components in Isolation
- Mock Hard to Reach Use Cases
- Document Use Cases as Stories
- Enhance with Addons
- Init Storybook
- npx -p @storybook/cli sb init
- Start Storybook
- yarn storybook
- Start Storybook
- yarn build-storybook
- in package.json "scripts": { ... "storybook": "start-storybook -p 9009 -s public", "build-storybook": "build-storybook -s public } netlify.toml - settings -add the file with content for deploying [build] base = "/" publish = "/storybook-static/" command = "yarn ci && yarn build-storybook"
- Loading Stories see the settings in -> .storybook/config.js
- must have extensions -> stories.js
- Adding Decorators
- Addons
- sending action in the storybook console in this case the name of the event is clicked(the event that was handled by action)
- import { action } from '@storybook/addon-actions';
- <Button onClick={action('clicked')}>
- in .storybook/config.js
- adding global decorator
- example: addDecorator(story => <div style={{ textAlign: "center"}}>{story()})
- in the example above the decorator will wrap the story in the div with these styles
Adding addon knobs - Storybook Addon Knobs allow you to edit props dynamically using the Storybook UI. You can also use Knobs as a dynamic variable inside stories in Storybook.
- npm i @storybook/addon-knobs or yarn add @storybook/addon-knobs --dev
- addon should be added in .storybook/addons.js like this: import '@storybook/addon-knobs/register';
- then import in .storybook/config.js : import { withKnobs } from '@storybook/addon-knobs' and then wrrapped it in decorator: addDecorator(withKnobs);
- check more complex example with meme-generator: 1h:18min
- test are documentation for your app, you can see all expected behavior of your functions, components and etc.
- when new joiner come to your code even if he messed up something the test will not passed
- motivates you to write high quality code with focus in you mind of separation of concerns
- keep you code tight, and easy to maintain
- when you change code not the behavior of the functions/components the test should passed
- Capture Regressions
- Ensure Proper Visual Content
- Validate UX
- Documentation
- Encourages High Quality Code
Jest Jest official site- 1h:35min
- Jest is a delightful JavaScript Testing Framework with a focus on simplicity.
- Fast and Safe
- Code Coverage
- Mocking API
- GOOD Exceptions
- Great Documentation
- Little to None
- Options Config
- package.json or jest.config.js
- Filename Conventions
- .js files in tests folders
- .test.js files
- .spec.js files
- Global Setup File:
- src/setupTests.js - in this file we can mock external API globally for the whole project in package.json "jest": { "snapshotSerializers": [ "enzyme-to-json/serializer" ], "collectCoverageFrom": [ "src/**/*.{js,jsx}", ], "coverageThreshold": { "global": { "branches": 100, "functions": 100, "lines": 100, "statements": 100 } } }
- describe - grouping scoping
- test/it - tests
- beforeAll/afterAll - one time scope/repeating scope
- beforeEach/afterEach - repeating before/ after every test
- expect(actual).matcher(expected) - assertion
- Smoke Tests
- Input - Output
- Behavior
- enzyme
- React Testing Libraries
Enzyme official site of enzyme
- Shallow Rendering - usualy for container components only to check if the compoenent is rendered
- Mount (Full) Rendering - for Integration tests
- Start at 1h: 52min
- Shallow rendering is useful to constrain yourself to testing a component as a unit, and to ensure that your tests aren't indirectly asserting on behavior of child components
- Testing components in isolation
- Container components
- Documenting Behavior
- Unit Testing
- Using shallow API
- creates ShallowWrapper
- componentDidMount and componentDidUpdate
- Full DOM rendering is ideal for use cases where you have components that may interact with DOM APIs or need to test components that are wrapped in higher order components
- Testing components integration
- Presentational Components
- Testing DOM elements interactions
- Browser-Like Environment
- Integration Testing
- Using mount API
- creates ReactWrapper
- mounts the component in the DOM
- Allows testing implementation details
- Relying on non-public interface
- Depending Components’ Names
- Asserting Component State
- Invoking Function Props
- jest-enzyme official site
- import 'jest-enzyme' in setupTests.js
- receiving a lot of good methods like toExist(), toHaveProp(), toHaveClassName(), toHaveValue() .etc..
- We try to only expose methods and utilities that encourage you to write tests that closely resemble how your web pages are used
- Builds on top of DOM Testing Library1
- Light-weight
- Works with actual DOM nodes
- Mock is an imitation, usually of lesser quality
- Mock objects are simulated objects that mimic the behavior of real objects in controlled ways, most often as part of a software testing initiative
- Isolate dependencies outside of our control
- Ensure we have passing tests
- Network (API) calls
- Date-related stuff
- Environment (e.g. env vars)
- Behaviors/Objects that aren’t target of the current test
- Timers
- jest.fn([implementation])1 - creates unused mocked function
- jest.spyOn(object, methodName)2 - wraps object[methodName] in mock function and returns the later
- mockFn.methods
- jest.useFakeTimers() - Instructs Jest to use fake versions of the standard timer functions
- jest.runAllTimers() - Exhausts both the macro-task queue and the micro-task queue
- jest.advanceTimersByTime(ms) - Executes only queued task in the macro task queue
- jest.runOnlyPendingTimers() - Executes only the macro-tasks that are currently pending
- Start with snapshot tests
- Inputs + Simulated Events = Output
- Use helper functions
- Place tests as close as possible to the implementation
- Changing implementation details (refactoring) should rarely cause a test to fail.
Text Manipulator react-proptypes-intellisense
- code --install-extension andys8.jest-snippets
- code --install-extension antmdvs.vscode-react-hooks-snippets
- code --install-extension azemoh.one-monokai
- code --install-extension bungcip.better-toml
- code --install-extension christian-kohler.npm-intellisense
- code --install-extension christian-kohler.path-intellisense
- code --install-extension dbaeumer.vscode-eslint
- code --install-extension DotJoshJohnson.xml
- code --install-extension dsznajder.es7-react-js-snippets
- code --install-extension eamodio.gitlens
- code --install-extension EditorConfig.EditorConfig
- code --install-extension eg2.vscode-npm-script
- code --install-extension EQuimper.react-native-react-redux
- code --install-extension esbenp.prettier-vscode
- code --install-extension formulahendry.code-runner
- code --install-extension jasonnutter.search-node-modules
- code --install-extension jeremyrajan.webpack
- code --install-extension kumar-harsh.graphql-for-vscode
- code --install-extension mgmcdermott.vscode-language-babel
- code --install-extension msjsdiag.debugger-for-chrome
- code --install-extension msjsdiag.vscode-react-native
- code --install-extension Orta.vscode-jest
- code --install-extension redhat.vscode-yaml
- code --install-extension streetsidesoftware.code-spell-checker
- code --install-extension timothymclane.react-redux-es6-snippets
- code --install-extension uloco.theme-bluloco-light
- code --install-extension vscode-icons-team.vscode-icons
- code --install-extension waderyan.babelrc
- code --install-extension xabikos.JavaScriptSnippets
- code --install-extension xabikos.ReactSnippets
- code --install-extension yzhang.markdown-all-in-one
- Reusing logic - desired
- Huge components - problem
- Confusing classes with React Class Components - problem
- Minified version won't minify method names
- Unused methods won't get stripped out
- Difficult with hot reloading and complier optimization
- Hooks are regular JavaScript functions that let you use React features (like state)
- Adoption Strategy: 1. No breaking changes 2. Minimum increase in package size ~ 1.5kb
useState => example: const [count, setCount] = useState(0), setCount is function for update the state(in the example count)
- Perform side effect from a function - data fetching, subscriptions, manual change of the DOM
- Serves the same purpose as componentDidMount, componentDidUpdate and componentWillUnmout
- Let's you specify how to 'clean up' by returning function
- Optimizing Performance
- Runs synchronously immediately after React has performed all mutations - Pretty much like useEffect but runs synchronously
- Useful for DOM measurements
- returns reference to the element that useRef is deployed
- useMemo - recomputes the memoized value when one of the dependencies has changed
- Ex: const memoizedValue = useMemo(() => computeExpensiveValue(a, b), [a, b]) - useful when fetching data only at certain moments not every time when the component is rendered
- Accepts a context object(the value returned from React.createContext) and returns the current context value for that context - usually used for themes
- Ex: const context = useContext(ThemeContext), const ThemeContext = React.createContext({color: 'dark'}), <-App value={context}>App-> => Then use it in every component : const theme = useContext(ThemeContext), you should import ThemeContext whenever you want to use it Change the value of the context only at highes level of you app where you included in the value prop
- Do not call hooks inside of conditional(if, switch) statements or for, while loops. Since all hooks are stored in something like an array with all hooks waiting to be resoled and if the hooks is inside of a if statement or while loop it can happened that the order of the hooks are changed caused of resolving some other hook instead of the disered one because your hook is inside of while loop or if statement.
- Only call hooks at the top level of your React functions
- Only Call Hooks from React Functions
- To enforce rules automatically use eslint-plugin-react-hooks
- Lets you extract extract component logic into reusable functions
- A custom Hook is a JavaScript function whose name starts with 'use' and that may call other Hooks inside of it usually useState(used for creating local isolated state for the custom hook) and useEffect(for using the cycle state of the components that using this custom hook)
- const useWindowSize = () => {
- const [size, setSize] = useState(window.innerWidth);
- useEffect(() => {
-
const handleResize = () => { -
setSize(window.innerWidth); -
}; -
window.addEventListener("resize", handleResize); -
return () => { -
window.removeEventListener("resize", handleResize); -
}; - });
- return size; *};
- Static Routing - routes are declared and execute before the app starts/renders
- Dynamic routing - routing takes place as your app is rendering not in a configuration or convention outside of a running app - Example: if you have in your app functionality for mobile devices and desktop devices you can easily make a condition in what cases which one should be called(in the render props of the Route)
- React Router Dom
- BrowserRouter - uses in 90% of the cases
- Uses regular URL paths - http://example.com/your/page
- Wrapped around browser's session history API so you can have cross platform experience
- Requires server configurations(react-create-app is doing that for us)
- We can also create route that will communicate with the server and the html it will be returned from the server it is used for optimizations(when we do not want to load everything from the client and the size of the client app will go down)
- HasRouter
- Stores the current location in the hash portion of the URL http://example.com/#/your/page
- No limitations of supported brwosers
- Renders some UI when its path matched the current URL
- Render methods props - component, render, children
- in component methods props is important not to have callback functions since when this route is rendered every time React will create a new instance of the component that is accepted
- Route props - match, location, history
- Ex:
- <Route path="/home" render={() => "div" Home "/div"}>
- <Route
- path={to}
- children={({match}) => (
- "li" className={match ? 'active': ''}>
- "/li"
- )}>
- params - Key/value pairs parsed from the URL corresponding to the dynamic segments of the path
- isExact - true if the entire URL was matched (no trailing characters)
- path -The path pattern used to match. Useful for building nested Routes
- url - The matched portion of the URL. Useful for building nested Links
- location - represent where the is now, where you want it to go, or even where is was the value of the location property is a object like this one => { key: 'ac3df4', pathname: '/somewhere', search: '?some=search-string', hash: '#howdy', state: { [userDefined]: true } } - the state object is the place where we can add some information that we would like to use in the navigation
history - wrapper around the several different implementations for managing session history in JavaScript in various environment: history property is mutable object
- length - The number of entities in the history stack(all the history paths are entries in this array like structure, length is the number of the paths that are in history stack)
- action - The current actions (PUSH, REPLACE or POP) - with this action we can realise what user has done. The action is PUSH when you call history.push, REPLACE when you call history.replace, and POP on initial load, when you call history.(go|goBack|goForward), and when you navigate using the browser's forward/back buttons.
- location - The current location stack. Only available in browser and memory history
- push(patch,[state]) - Pushes a new entry onto the history stack - This is how we make navigation in our app
- go(n) - Moves the pointer in the history stack by n entries
- replace(path, [state]) - Replace the current entry on the history - This is how we make redirect good suit for Login
- goBack() - Equivalent to go(1)
- goForward() - Equivalent to go(-1)
withRouter(HOC) - passes match, location and history props to the wrapper component whenever it renders: import {withRouter} from 'react-router'
- const ShowTheLocation () => Login; const ShowTheLocationWithRouter = withRouter(ShowTheLocation)
Switch - when we wrap our Routes compoents the order of the Route compoentns is very important since when the Switch hit the first Route component it stops looking further
- Renders a router exclusively. In contrast, every Route that matches the location renders inclusively
- Link - Create links in your application
- NavLink - Special type of that can style itself as "active" when its to props matches the current location
- Redirect - Will navigate using its to prop
- Demo Route authentication from the official documentation
- Demo in the video - ~ 1h: 13min - with small changes from the official documentation
- Ex: const BlogPost ({ match }) => { const slug = match.props } === const BlogPost() { const { slug } = useParams()} - analogical is for all React hooks
- useParams()
- useHistory()
- useLocation()
Code splitting Official documentation Code Splitting - Instead of downloading the entire app before users can use it, code splitting allows you to split your code into small chunks which you can then load on demand.
- Bundling - following imported files and merging then into single file : a "bundle" - basically Bundling is: a tool(Webpack in React) going into the files in your application and creating Dependency Graph and then all files based on this Dependency Graph are merged into one file called "bundle". Bundling is very helpful for optimizations and Webpack is stripping the files that are not used.
- Bundling is very helpful for areas where the internet is with bad quality and the need for loading less is on demand
- Laziness - an evaluation strategy which delays the evaluation of an expression until its value is needed
- Code Splitting - Slice a code base into smaller chunks that can be loaded on-demand
- Dynamic import => Ex with Dynamic imports import("math").then(math => console.log(math.add(16, 26))); - when Webpack go through files and see this syntax Webpack is putting this file in separate bundle
- Ex without dynamic imports => import { add } from './match'
- React.lazy
- Ex without React.lazy import OtherComponent from './OtherComponent;
- Ex with React.lazy const OtherComponent = React.lazy (() => import('./OtherComponent)); - this component will be load in the moment when we are going to rendered or when is needed
- Allow us to show fallback content
- Ex:
- const OtherComponent = React.lazy(() => import('./OtherComponent'));
- const MyComponent = () => {
- return (
-
<> -
<Suspense fallback={'div'...Loading'...div'}> -
<OtherComponent> -
<Suspense> -
</> - )
- }
- fallback property is a way to show different content on the screen during the time when is loading
- Ex:
- import { BrowserRouter as Router, Route, Switch } from 'react-router-dom';
- import React, { Suspense, lazy } from 'react';
- const Home = React.lazy(() => import('./routes/Home'));
- const About = React.lazy(() => import('./routes/About'));
- const App = () => {
-
<Router> -
<Suspense fallback={'div'...Loading'...div'}> -
<Switch> -
<Route exact path='/' component={Home}> -
<Route exact path='/about' component={About}> -
</Switch> -
<Suspense> -
</Router> - )
- }
- 1h:35min from the video
- React Profiler official documentation
- Render phase - determines what changes need to be made to e.g. the DOM - is the moment when React decide what kind of changes needs to be applied to the DOM
- Commit phase - React applies any changes - the moment when React is applied the changes to the DOM
- Profiler ignores Render phase and working only with the Commit phase
- Traditional REST
- What is GraphQL
- Concepts in GraphQL
- data is request from the client to the restful back-end through http protocol
- the idea is the everything it our system is called resource and fetch through url(end-point)
- There is not limit in the format of data that will be returned is can by xml, json ...
- Uniform interface -we always use the http verbs(GET, POST, PUT, PATCH DELETE)
- Stateless - each request is self-descriptive
- Clint-server - client should be separated from the server, so each of them can be developed individually
- Cashable - caching shall be applied to resources applicably and those resource should be explicitly marked as cashable
- New API standard that enables declarative data fetching
- Developed internally at Facebook in 2012 and open sourced in 2015
- Exposes a single endpoint (ass opposed to REST) and responds only with the data requested from the client
- Aims to provide more powerful and flexible alternative to REST
- provides declarative data retrieval istead of imperative
- remove overfetching and underfetching (n+1 problem)
- improves rapid development
- we ca get as much data as we want with a single request to the database
- Type Schema Definition Language (SDL)
- Type system
- Queries
- Mutations
- Client
- Server
- GrapthQL has own type system that is used to define the schema of the API
- The syntax for writing schemas is called SDL
- Example: -> type Person { name: String! age: Int! posts: [Post!]! } ; type Post { type: String! author: Person! }
- When we have ! -> is non nullable -> it means that this field is required when we making queries. posts:[Post!]! is List(array) with Post type objects
- Example: { person { id name } }
- The query starts from special "root" object
- From that object, select the person field
- For the object returned for the person field, select id and name
- Every GraphQL server defines a schema which describe the set of possible data that can be queried
- The schema answers the following questions
- What types can be queried?(e.g Person and Post)
- What fields/sub-fields can be selected?
- What is the actual type of a field?(e.g String, Int..)
- By default, all types in GraphQL are nullable; the null value is a valid response for all of the above types. To declare a type that disallows null, the GraphQL Non‐Null type can be used. This type wraps an underlying type, and this type acts identically to that wrapped type, with the exception that null is not a valid response for the wrapping type. A trailing exclamation mark is used to denote a field that uses a Non‐Null type like this: name: String!.
- The basic components fo GraphQL schema are Object types
- It's just an object with fields
- Example: type Person { name: String! posts: [Post!]!}
- Person is GraphQL Object Type
- String! means that the name filed is of the type string and in non-nullable
- [Posts!]! means that the posts field is an array of non-nullable Post objects and that the array itself in non-nullable
- Every field can have aero or more arguments
- The arguments can be optionsl and required
- Passed by name (unlike function arguments in JS)
- Example: type Person { name: String! posts(first: Int = 3): [Post!]! }
- Special object types that act like the entry point of the API
- Query is mandatory for every schema(this is the root of our entry point and needs to be Query), Mutation is optional
- Example: query { person { name } } , type Query { person: Person } -> in th
- Scalar types are the leaves of the query(they don't have sub-fields)
- Int - A signed 32-bit integer
- Float - A signed double-precision floating-point value
- String - A UTF-8 character sequence
- Boolean - true or false
- ID - unique identifier used for caching
- Special kind of scalar restricted to a particular set of values
- Example: enum PersonTYpe { USER ADMIN } => type Person { type: PersonType }
- Interfaces are abstract types that define set of fields
- Example interface Person { id: Int name: String }, type User implements Person { id: Int name: String } posts: [Post!]! }, type Admin implements Person { id: Int name: String adminRoles: [Role!]! }
- Example with the Schema above: query { person { id name } ... on User { posts { title } } ... on Admin { adminRoles } }
- response will be from the query above: { "data": { "persons" : [ "id": 1, "name": "User", "posts": [{"title": "Some post"}], "id": 2, "name": "Admin", "adminRoles": [{"name": "moderator"} ] } }
- In GraphQL query, every field can get it's own set of arguments
- Example: { person(id: 1) { name posts(title: "graphql") { id content } } }
- It's possible to request the same field mulptiple times in a single query
- Example: { query { { person(id: 1) { name } person(id: 2) { name } } } } => It will become { query { { normalUser: person(id: 1) { name } adminUser: person(id: 2) { name } } } }
- very useful in big queries with 200 - 300 fields
- Allows us to reuse parts of the query
- Definition of fragments Example: fragment PersonFields on Person { id name }, { query { normalUser: person(id: 1) { ... PersonFields } adminUser: person(id: 2) { ... PersonFields } } }
- Provides a way to remove the hard-coded query arguments
- The variables dictionary is passed in the body of the HTTP request
- Example: { query personWithPosts$id: Int!, $first: int) { person(id: $id) { name posts(first: $first) { title } } } } - and in the GraphiQL in the section of QUERY VARIABLES(DOWN LEFT SECTION) we adding the value of the id like this -> { "id": 1 }, the body of our post request will be { operationName: "personWithPosts", query: "{ person(id: $id) { name posts(first: $first) { title } } }", variable: { id: 1 } }
- Used to dynamically change the shape and structure of queries
- Example: query Person($id: Int, $withPost: Boolean!) { person(id: $id) { name posts @include(if: $withPosts) { name } } }
- A directive can be attached to any field or fragment inclusion
- Can affect the execution of the query in any way the server desires
- The GraphQl Spec includes two directives @include(if: Boolean) - it will include this field if the argument is true and @skip(if: Boolean) - it will skip if the argument is true
- Server implementations may have some experimental directives
- return the type of a field
- It is useful when we need the type field for rendering purposes in the project will need it!
- In some cases we need to know the return type of a field
- Include the __typename field at any point of the query to get the return type of that field
- Example: { query { **typename id { { normalUser: person(id: 1) { ... PersonFields } } { **typename id adminUser: person(id: 2) { ... PersonFields } } } } } and the response will be something like: { "data": { "persons" : [ { "**typename": "User", "id": 1, "name": "User", "posts": [{"title": "Some post"}] }, {"**typename": "Admin", "id": 2, "name": "Admin", "adminRoles": [{"name": "moderator"} ] } } }
- By convention Queries only fetch data and don't couse side effects
- For side effects and data chages use Mutations
- Example: type PersonInput { name: String age: Int } , mutation CratePerson($input: PersonInput) { createPerson(input: $input) { id name } } - in the curly brackets this is the result returned from the back-end we can start using the same syntax when we writing a query and use the result(id and name) in this query
- __schema { types queryType mutationType subscriptionType directives } - returns all types custom and build-in from our schema
- Example: { **schema { types { name } } } -> response will be: { "data": { "**schame": { "types" : [ { "name": "Query"}, { "name": "Person" }, ... ] } } }
- __type { kind name description fields interfaces possibleTypes enumValues inputFields ofType } - returns information about type in our Schema
- Example: { **type(name: "User") { name interfaces { name } } } -> response will be: { "data": { "**type": { "name": "User", "interfaces": [ { "name": "Person" } ] } } }
- more examples from the video ~ 1h of the video
- react-reselect-and-redux
- react-dev-tools-debug-like-a-ninja
- testing-recipes
- jest doc
- shollow wrapper enzyme
- how-to-add-custom-message-to-jest-expect
- writing-snapshot-tests-for-react-components-with-jest
- testing-react-hook-state-changes-2oga
- understanding-jest-mocks
- testing-react-jest-enzyme-sinon
- how-to-mock-specific-module-function-in-jest
- mock-spy-exported-functions-within-a-single-module-in-jest
- mocking-the-current-date-in-jest-tests
- can-you-console-log-in-jsx
- introduction-of-react-js-debugging
- getting-started-react-logging
- organizing-tests-in-jest
- how-to-test-a-react-component-that-is-dependent-on-usecontext-hook
- testing-react-with-jest-and-enzyme
- test-isolation-with-react
- mocking-the-current-date-in-jest-tests
- Daishi Kato blog
- how-to-create-react-custom-hooks-for-data-fetching-with-useeffect
- react-tracked-documentation-website-with-docusaurus-v2
- react-tracked-documentation-website-with-docusaurus
- writing-your-own-react-hooks-simplified
- react-hooks-guide
- setting-state-of-nested-array-with-react-hooks
- building-custom-react-hooks
- management-usecontext-useeffect-usereducer
- useeffect-vs-uselayouteffect
- hooks API
- react-hooks-cheat-sheet-unlock-solutions-to-common-problems
- a-complete-guide-to-useeffect
- react-hooks-fetch-data
- How to use Redux with React Hooks
- react-usecontext-hook
- redux-vs-usereducer
- react-redux-apollo-client-state-management-tutorial
- the-only-introduction-to-redux-and-react-redux-youll-ever-need
- can-i-dispatch-multiple-actions-from-redux-action-creators/
- The definitive guide to redux-persist
- should-i-store-function-references-in-redux-store
- life-after-redux
- environments-with-create-react-app-7b645312c09d
- comparing-bundlers-webpack-rollup-parcel
- how-to-setup-react-parcel-boilerplate-project
- npm-install official doc
- my-journey-to-make-styling-with-material-ui-right-6a44f7c68113
- internationalizing-a-front-end-application
- color-psychology-psychologica-effects-of-colors
- adding-fonts-to-create-react-app
- stop-using-bootstrap-create-a-practical-css-grid-template-for-your-component-based-ui
- everything-you-need-to-know-about-loading-animations
- design-for-the-dark-theme
- container-vs-presentational-components-in-react****
- functional-composition-of-react-components
- react-composition-patterns-from-the-ground-up
- react-router-v5-1
- implementing-private-routes-with-react-router-and-hooks
- Understanding_Using_Links_React_Router
- react-lazy-suspense-and-concorrent-react-breakdown-with-examples
- why-react-suspense-will-be-a-game-changer
- adventuring-into-react-hooks-performance-practices
- optimizing-performance
- react-profiler-in-depth
- Arrow_functions
- Event Loop
- composition-over-inheritance
- 12-tips-for-writing-clean-and-scalable-javascript
- Inheritance_and_the_prototype_chain
- deprecating-the-switch-statement-for-object-literals
- why-are-my-variables-undefined-when-using-debugger-in-chrome-devtools
- why-does-chrome-debugger-think-closed-local-variable-is-undefined -javascript-underpinnings-execution-context-stack-event-loop-task-queue-runtime
- https://medium.com/javascript-in-plain-english/functional-programming-higher-order-function-hof-aaa46bb444bb
- best-visual-studio-code-extensions-for-programmers
- vs-code-extensions-for-complete-ide-experience
- the-most-powerful-tool-to-boost-your-coding-productivity
- snippet generator
- guide-docker-commands-examples
- an-introduction-to-environment-variables-and-how-to-use-them
- process-env-what-it-is-and-why-when-how-to-use-it-effectively
- github-authorization
- best-visual-studio-code-extensions-for-programmers
- locking-down-a-project-to-a-specific-node-version-using-nvmrc-and-or-engines
- absolute-imports-with-create-react-app
- comparing-bundlers-webpack-rollup-parcel
- what-are-rc-files-in-nodejs
- or set up automatic nvm use call
- locking-down-a-project-to-a-specific-node-version-using-nvmrc-and-or-engines
- progress-bar-with-react-hooks
- practical-tips-for-cheating-at-design
- how-to-customize-material-ui-theme-part-1-understanding-mui-theme-structure-and-how-to-read-doc
- how-to-customize-material-ui-theme-part-2-override-global-variables-and-tools
- how-to-customize-material-ui-theme-part-3-overrode-component-variables -
- min-width-max-width-media-queries
- overflowhidden-dots-at-the-end
- GrapghQl Tutorial
- graphql-apollo-server-tutorial
- apollo-client-now-with-react-hooks
- testing-apollos-query-component
- getting-started-with-react-and-graphql
- easy-configuration-graphql-server-with-apollo-server-2-and-firebase-cloud-functions-google-cloud-4c1b46dd98f6
- build-a-simple-blog-with-graphql-node-js-sqlite-and-vue-angular-or-reactjs
- the-done-is-better-than-perfect-approach-to-programming
- good-code-vs-bad-code
- Cyclomatic_complexity
- wtf-per-minute-actual-measurement-for https://12factor.net/
- The Twelve Factors principles
- Rules of Thumb. - Computer Science
- locking-down-a-project-to-a-specific-node-version-using-nvmrc-and-or-engines
- form-validation-with-hook-in
- composition-over-inheritance
- documenting-react-components-with-storybook
- understanding-react-default-props
- react-children-composition-patterns-with-typescript
- practical-beginners-guide-to-regex-regular-expressions
- Rules of Thumb. - Computer Science
- managing-packages-with-github-packages
- Git-Basics-Tagging
- what-is-git-tag-how-to-create-tags-how-to-checkout-git-remote-tags
- better-commit-messages-with-a-gitmessage-template
- gitignore standart patterns
- github-authorization
- managing-a-workflow-run
- automating-your-workflow-with-github-actions
- host-webapps-free
- Digital Ocean
- how-to-deploy-your-react-application-to-github-pages-in-less-than-5-minutes
- 10-tips-tricks-that-will-make-you-a-better-reactjs-dev-4fhn
- tips-and-tricks
- visual-studio-code-formatting-setup
- write-cleaner-code-using-prettier-and-eslint-in-vscode
react-components-naming-convention
how-to-use-super-keyword-in-typescript
- build-a-react-native-app-with-react-hooks
- react-native-tips-setting-up-your-development-environment-for-windows
- react-typescript-cheatsheet-USED*
- why-typescript-guideline-USED*
- typescript-type-string-undefined-is-not-assignable-to-type-string *USED
- facebook-login-in-react-native-apps
- facebook-login-ios-for-react-native-using-facebook-sdk
- login-with-facebook-and-google-in-reactjs
- enforce-https-facebook-login*USED
build-a-simple-blog-with-graphql-node-js-sqlite-and-vue-angular-or-reactjs graphql-apollo-server-tutorial
-
git actions, lerna, husky, eslint, tslint, lint-staged
- utilizing-git-hook-by-using-eslint-husky-and-lint-staged-INFO*
- husky-in-multiple-projects-INFO*
- 2-minute-revolution-developer-blog/our-full-linting-and-commit-setup-for-typescript-prettier-tslint-lint-staged-husky-USED*
- code sharing in big multi repo projects-INFO*
- git and multiple repo-INFO*
- git actions and lerna-INFO*
- shipping-multipackage-repos-with-github-actions-changesets-and-lerna-USED*
- Computer Science 1
-
There are many areas where this rule applies in programming. Two very important ones are:
-
a) Subprogram behavior and length: Subprograms should do precisely ONE conceptual task and no more. The length of a subprogram should allow it to be easily visually _ inspected; generally no more that one page in length. Similarly you should generally not mix input/output and algorithmic logic in the same subprogram; it is alway a goal _ to separate I/O from logic.
-
b) If a problem is can be decomposed into two or more independently solvable problems, then solve them independently and after you have implemented and tested the * independent solutions, then combine them into the larger result. This is sometimes known as "Gall's Law":
-
"A complex system that works is invariably found to have evolved from a simple system that worked. The inverse proposition also appears to be true: A complex system * designed from scratch never works and cannot be made to work. You have to start over, beginning with a working simple system."
-
is a code refactoring rule of thumb to decide when a replicated piece of code should be replaced by a new procedure. It states that you are allowed to copy and paste the _ code once, but that when the same code is replicated three times, it should be extracted into a new procedure. The rule was introduced by Martin Fowler in his text _ "Refactoring" and attributed to Don Roberts.
-
Duplication in programming is almost always in indication of poorly designed code or poor coding habits. Duplication is a bad practice because it makes code harder to _ maintain. When the rule encoded in a replicated piece of code changes, whoever maintains the code will have to change it in all places correctly. This process is _ error-prone and often leads to problems. If the code exists in only one place, then it can be easily changed there. This rule is can even be applied to small number of _ lines of code, or even single lines of code. For example, if you want to call a function, and then call it again when it fails, it's OK to have two call sites; however, if _ you want to try it five times before giving up, there should only be one call site inside a loop rather than 5 independent calls.
-
The ninety-ninety rule is a humorous aphorism that states:
-
"The first 90 percent of the code accounts for the first 90 percent of the development time. The remaining 10 percent of the code accounts for the other 90 percent of the * development time."
-
—Tom Cargill, Bell Labs
-
That the total development time sums to 180% is a wry allusion to the notorious tendency of software development projects to significantly overrun their original schedules. _ It expresses both the rough allocation of time to easy and hard portions of a programming project and the cause of the lateness of many projects (that is, failure to _ anticipate the hard parts). In other words, it takes both more time and more coding than expected to make a project work.
-
Never sacrifice clarity for some perceived efficiency. One of the biggest mistakes that new programmers make is tweaking code to remove a couple of textual lines of high _ level code and replace it with a much more complex single line of code. This is commonly called "bit twiddling". Always remember that most compilers optimize code. _ Further, there is a corollary to the 90-90 rule known as the "Pareto Principle":
-
In computer science, the Pareto principle can be applied to resource optimization by observing that 80% of the resources are typically used by 20% of the operations. In _ software engineering, it is often a better approximation that 90% of the execution time of a computer program is spent executing 10% of the code (known as the 90/10 law in _ this context).
-
Given this knowledge, most "bit twiddling" will have no perceivable impact on the runtime of most programs as most of them will likely be in the 90% of code that has little _ impact on the run-time of the program. The real efficiency gains come from changing the order of complexity of the algorithm, such as changing from O(N^2) to O(NlogN) _ complexity. Keep your code clearly and cleanly written and it will usually be reasonably efficient. Occasionally, after the program is written and tested, it might prove _ to be slower than the problem specification calls for. On the these few occasions, and only after you have first optimized the complexity of the algorithm, then instrument _ or profile the code and find the 10% or less of the code that PROVABLY causes slow runtime and then optimize that small code segment.
-
Comments on this topic from well respected computer scientists and software engineers:
-
"More computing sins are committed in the name of efficiency (without necessarily achieving it) than for any other single reason — including blind stupidity." — W.A. Wulf
-
"We should forget about small efficiencies, say about 97% of the time: premature optimization is the root of all evil. Yet we should not pass up our opportunities in that _ critical 3%. A good programmer will not be lulled into complacency by such reasoning, he will be wise to look carefully at the critical code; but only after that code has _ been identified" — Donald Knuth
-
"Bottlenecks occur in surprising places, so don't try to second guess and put in a speed hack until you have proven that's where the bottleneck is." — Rob Pike
-
"The First Rule of Program Optimization: Don't do it. The Second Rule of Program Optimization (for experts only!): Don't do it yet." — Michael A. Jackson
-
In computer programming, a naming convention is a set of rules for choosing the character sequence to be used for identifiers which denote variables, types and functions * etc. in source code and documentation. Reasons for using a naming convention (as opposed to allowing programmers to choose any character sequence) include the following:
-
- to reduce the effort needed to read and understand source code which supports its maintainability
-
- to enhance source code appearance (for example, by disallowing overly long names or unclear abbreviations)
-
There are lots of naming conventions that are strongly argued for or against by various engineers; in reality these are mostly religious arguments. However, whatever you _ do, you should follow some consistent naming style. There is one thing that is common to most all naming conventions, and that is that the name should be descriptive of _ the contents, or a name that is in common programming practice for the language (such as using i, j, k for loop and array indexes).
-
Commonly, subprograms should have verb/verb phrase names as a subprogram should specify one specific task (see KISS rule) which should be an activity description. Variables _ should have noun or adjective names as variables represent things or attributes of something. When choosing a name, if you have difficulty in coming up with a descriptive _ name this is an indication that your code needs further refactoring to improve the clarity of the design and the purpose of subprograms and variables.