Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -8,16 +8,22 @@
"@testing-library/react": "^13.4.0",
"@testing-library/user-event": "^13.5.0",
"@types/d3": "^7.4.0",
"@types/dompurify": "^3.0.3",
Copy link
Copy Markdown
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

the library is not used

"@types/jest": "^27.5.2",
"@types/node": "^16.18.25",
"@types/react": "^18.2.0",
"@types/react-dom": "^18.2.1",
"@types/showdown": "^2.0.2",
Copy link
Copy Markdown
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

the library is not used

"antd": "^5.7.3",
"d3": "^7.8.5",
"dompurify": "^3.0.6",
Copy link
Copy Markdown
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

the library is not used

"react": "^18.2.0",
"react-dom": "^18.2.0",
"react-markdown": "^9.0.0",
"react-scripts": "5.0.1",
"remark-gfm": "^4.0.0",
"sass": "^1.69.0",
"showdown": "^2.1.0",
Copy link
Copy Markdown
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

the library is not used

"typescript": "^4.9.5"
},
"scripts": {
Expand Down
35 changes: 17 additions & 18 deletions src/App.tsx
Original file line number Diff line number Diff line change
@@ -1,30 +1,29 @@
import React from 'react';
import React, {useEffect, useRef} from 'react';
Copy link
Copy Markdown
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do we need to import react?

import Layout from "./components/Layout/Layout";
import Expertise from "./features/Expertise";
import Experience from "./features/Experience";
import CircularPacking from "./features/CircularPacking/CircularPacking";

function App() {

import Markdown from "./components/MarkdownComp";
Copy link
Copy Markdown
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
import Markdown from "./components/MarkdownComp";

import AboutMe from "./features/AboutMe";

return (
<>
<Layout components={[
{
title: '',
content: <CircularPacking />
},{
title: 'Davide Grimaldi',
subtitle: 'Software Engineer, Front end & App Developer.'
},{
function App() {
return (
<Layout components={[
{
title: '',
content: <CircularPacking />
},{
title: 'Davide Grimaldi',
subtitle: `Software Engineer, Front end & App Developer.`,
content: <AboutMe />
},{
title: 'My Expertise',
content: <Expertise />
content: <Expertise />
},{
title:'Professional Experience',
content: <Experience />
}
]}/>
</>
content: <Experience />
}]}/>
);
}

Expand Down
21 changes: 21 additions & 0 deletions src/components/MarkdownComp.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
import showdown from 'showdown';
import {sanitize} from 'dompurify';
import {memo} from "react"
import Markdown from "react-markdown";
import remarkGfm from 'remark-gfm'


const MarkdownComp = memo(function MarkdownComp({text, title}: {text: string, title?: string | ""}) {

const converter = new showdown.Converter();
Copy link
Copy Markdown
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

we don't use this variable. Do we need it?

const cleanHTML = sanitize(converter.makeHtml(text))
Copy link
Copy Markdown
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

we don't use this variable. Do we need it?


return (
<>
<title>{title}</title>
<Markdown remarkPlugins={[remarkGfm]}>{text}</Markdown>
</>
)
})

export default MarkdownComp
5 changes: 5 additions & 0 deletions src/components/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
# 🗺 Davide's Portfolio

Welcome to my portfolio guide where I provide a walkthrough to my data projects.

Chat with me on davide_grimaldi@hotmail.com about my projects!
44 changes: 35 additions & 9 deletions src/features/AboutMe.tsx
Original file line number Diff line number Diff line change
@@ -1,13 +1,39 @@
import Item from "../interfaces/Item";
import {Card} from "antd";
import {Button, Card, Modal, Pagination} from "antd";
import React, {useState} from "react";
import {codeReview} from "./Markdown/codeReview";
import {memoization} from "./Markdown/memoization";
import {referencing} from "./Markdown/referencing";
import MarkdownComp from "../components/MarkdownComp";

const aboutMe: Item = {
key: "about",
node: <Card>
I aim to attain an engaging developer position in the field software development. I have five years as software developer in work experience and two years in academic experience.
I'm proactive person and I like to invest time to learn, then to share and to discuss new solution to the other member of my team. I'm diabetic, this does not involve any physical impediments</Card>,
title: "About",
href: '#about'
// const aboutMe: Item = {
// key: "about",
// node: <Card>
// I aim to attain an engaging developer position in the field software development. I have five years as software developer in work experience and two years in academic experience.
// I'm proactive person and I like to invest time to learn, then to share and to discuss new solution to the other member of my team. I'm diabetic, this does not involve any physical impediments</Card>,
// title: "About",
// href: '#about'
// }

const AboutMe = () => {
const [isModalOpen, setModalOpen] = useState(false)
Copy link
Copy Markdown
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could we use a different name for set. Something like updateIsModalOpen?

const markdownTextList = [codeReview, memoization, referencing]
const [selectedMarkdown, setSelectedMarkdown] = useState(1)
return (
<div style={{display: "flex"}}>
<Modal
open={isModalOpen}
okButtonProps={{ style: { display: "none"} }}
Copy link
Copy Markdown
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can we move all the styles in appropriate file or in an external variable?

cancelButtonProps={{ style: { display: "none"} }}
onCancel={()=> setModalOpen(false)}
width={2000}
>
<MarkdownComp text={markdownTextList[selectedMarkdown - 1]} />
<Pagination simple total={30} onChange={(page)=> setSelectedMarkdown(page)} />
Copy link
Copy Markdown
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can we externalize the variable? maybe not an hard-coded number but related to markdowns' number

</Modal>
<Button type="default" style={{flex: "1 100%"}} onClick={()=> setModalOpen(!isModalOpen)}>Read my Markdown</Button>
</div>
)
}

export default aboutMe
export default AboutMe
43 changes: 43 additions & 0 deletions src/features/Markdown/codeReview.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
export const codeReview =`1. Check if there are any new npm packages added.

2. Check if there is no functionality duplicates like date-fns + moment.

3. Also check for imports, as sometimes tree shaking is not working as you wish, and you could bundle the whole library and use just a single method like the below:

import _ from 'lodash';
//should became more precise import like:
import uniq from 'lodash/uniq';

4. If your app is using translations – check if all new areas have also translations. If not, point that out and the developer should be aware of that in the future.

const NewComponent = () => {
return (<div> New static text inside new component should be translated!</div>)
}

5. Check for missing or invalid types if you are using TypeScript. All “ANY” types should also be fixed unless you have a really, really good explanation for not doing so. Below we have missing props types and any in the method.

const NewComponent = ({items, data}) => {
const getItemId = (data: any) => data.id
return (
<div>
{items.map(item => (
<span key={getItemId(item)}>
<h1>{item.title}</h1>
<p>{item.description}</p>
</span>
))}
</div>
)}
6. Check for variables, functions, and naming conventions. They should all declare what they are and what they do.
7. For boolean values, use prefixes is/are/should to declare their behaviour (visible => isVisible) to avoid treating them as HTML properties.
8. Ensure functions declare their purpose, and if they return anything, name them accordingly. For example, if they manipulate data: updateUsers => addUniqId, parseData => parseToAPIFormat, etc.
9. Check for weird logic patterns (things you have never seen before). Sometimes when a React developer takes too much time on a single task – they start to be really creative while writing code and create methods or flow that have no sense at all and can destroy the project structure. You should provide feedback and suggest more suitable solutions to provide a better code.
10. Check for too complicated code chunks. If someone is adding an ID into an array using 20 lines of code instead of 1, take some actions. Or when you are using some 3rd party packages like lodash, but the developer keeps writing all the methods by himself.
11. If you can’t understand what a specific chunk of code is doing, add descriptive comments to clarify its purpose. Alternatively, request an explanation from the developer to avoid future confusion.
12. Check for hardcoded names, paths, and values. Separate that kind of code, so you can easily change it in one place. Use paths instead. They are (in most cases) used in routing configuration and in every link and redirection. Also, separate types, date formats and everything that can be used in multiple places – to easily change them.
13. Check for backward compatibility issues like changes in props from optional to required. Or changes in some methods’ parameter types. If you made such a change with TypeScript – it should throw a compilation error. If you are using just JavaScript – you need to track that manually.
14. Check for code repetition. If you’ve seen the same/similar logic in multiple places – point that out. Code should be reusable and if you will need to update that logic, you will have to update it in a single place. Not 3 of them.
15. Check for missing form validations or incorrect form validations. I’ve never seen React apps that have a form without field validation.
16. Check for missing error handlers from API responses to provide appropriate feedback to users. Pay attention to try/catch blocks and their handling in catch.
17. Check for async methods – can they be done in parallel, or do we need all the data in a sequence? Check if we actually wait for this data if we need it, or if we read from the promise object.
18. Sometimes you may notice potential bugs. A big part of knowledge comes with experience. If you are a good React developer and see something you’ve done in the past, but it caused errors – don’t make it happen again. Explain that you’ve been there, and you know the way out as you’ve made it work before.`
64 changes: 64 additions & 0 deletions src/features/Markdown/memoization.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
export const memoization = `
**Memoization**

With *memo*, you can create a component that React will not re-render when its parent re-renders so long as its new props are the same as the old props. Optimizing with memo is only valuable when your component re-renders often with the same exact props, and its re-rendering logic is expensive. If there is no perceptible lag when your component re-renders, memo is unnecessary. Keep in mind that memo is completely useless if the props passed to your component are always different, such as if you pass an object or a plain function defined during rendering. This is why you will often need useMemo and useCallback together with memo.

const Chart = memo(function Chart({ dataPoints }) {// ...
}, (oldProps, newProps) => {return oldProps == newProps} //optionals);


*useCallback* caches a function between re-renders until its dependencies change: useCallback(fn, dependencies)

- fn: React will give you the same function again if the dependencies have not changed since the last render

- dependecios: are the list of all reactive values referenced inside of the fn code. Reactive values include props, state, and all the variables and functions declared directly inside your component body.

example

// ...
const handleSubmit = useCallback((orderDetails) => {
post('/product/' + productId + '/buy', {
referrer,
orderDetails,
});
}, [productId, referrer]);
// ...
<ShippingForm onSubmit={handleSubmit} /
// ...
const ShippingForm = memo(function ShippingForm({ onSubmit }) {
// ...
});

Caching a function with useCallback is only valuable in a few cases:

- You pass it as a prop to a component wrapped in memo. You want to skip re-rendering if the value hasn’t changed. Memoization lets your component re-render only if dependencies changed.
- The function you’re passing is later used as a dependency of some Hook. For example, another function wrapped in useCallback depends on it, or you depend on this function from useEffect.


*useMemo*


The difference is in what they’re letting you cache:


import { useMemo, useCallback } from 'react';
function ProductPage({ productId, referrer }) {
const product = useData('/product/' + productId);
const requirements = useMemo(() => { // Calls your function and caches its result
return computeRequirements(product);
}, [product]);
const handleSubmit = useCallback((orderDetails) => { // Caches your function itself
post('/product/' + productId + '/buy', {
referrer,
orderDetails,
});
}, [productId, referrer]);
return (
<div className={theme}>
<ShippingForm requirements={requirements} onSubmit={handleSubmit} />
</div>
);
}

- useMemo caches the result of calling your function. In this example, it caches the result of calling computeRequirements(product) so that it doesn’t change unless product has changed. This lets you pass the requirements object down without unnecessarily re-rendering ShippingForm. When necessary, React will call the function you’ve passed during rendering to calculate the result.
- useCallback caches the function itself. Unlike useMemo, it does not call the function you provide. Instead, it caches the function you provided so that handleSubmit itself doesn’t change unless productId or referrer has changed. This lets you pass the handleSubmit function down without unnecessarily re-rendering ShippingForm. Your code won’t run until the user submits the form.`
93 changes: 93 additions & 0 deletions src/features/Markdown/referencing.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,93 @@
export const referencing = `**Referencing**

When you want a component to “remember” some information, but you don’t want that information to trigger new renders, you can use a *ref*.



import { useRef } from 'react';
export default function Counter() {
let ref = useRef(0);

function handleClick() {
ref.current = ref.current + 1;
alert('You clicked ' + ref.current + ' times!');
}

console.log("render only first time")

return (
<button onClick={handleClick}>
Click me!
{ref.current} //Error! You’d never see the count change
</button>
)}


*Differences between refs and state*
Perhaps you’re thinking refs seem less “strict” than state—you can mutate them instead of always having to use a state
setting function, for instance. But in most cases, you’ll want to use state. Refs are an “escape hatch” you won’t need
often. Here’s how state and refs compare:

| refs | state |
|------------------------------------------------------------------------------------|:-----:|
| useRef(initialValue) returns { current: initialValue } |useState(initialValue) returns the current value of a state variable and a state setter function ( [value, setValue])|
| Doesn’t trigger re-render when you change it. |Triggers re-render when you change it.|
| Mutable—you can modify and update current’s value outside of the rendering process.|“Immutable”—you must use the state setting function to modify state variables to queue a re-render.|
| You shouldn’t read (or write) the current value during rendering. |You can read state at any time. However, each render has its own snapshot of state which does not change.|


*When to use refs*

Typically, you will use a ref when your component needs to “step outside” React and communicate with external APIs—often
a browser API that won’t impact the appearance of the component. Here are a few of these rare situations:

- Storing timeout IDs
- Storing and manipulating DOM elements, which we cover on the next page
- Storing other objects that aren’t necessary to calculate the JSX.

*DOM*
React automatically updates the DOM to match your render output, so your components won’t often need to manipulate it.
However, sometimes you might need access to the DOM elements managed by React—for example, to focus a node, scroll to
it, or measure its size and position. There is no built-in way to do those things in React, so you will need a ref to
the DOM node.

import { forwardRef, useRef } from 'react';
const MyInput = forwardRef((props, ref) => {
return <input {...props} ref={ref} />;
});

export default function Form() {
const inputRef = useRef(null);

function handleClick() {
inputRef.current.focus();
}

return (
<>
<MyInput ref={inputRef} />
<button onClick={handleClick}>Focus the input</button>
</>
);}

In React, every update is split in two phases:

- During render, React calls your components to figure out what should be on the screen.
- During commit, React applies changes to the DOM.

In general, you don’t want to access refs during rendering. That goes for refs holding DOM nodes as well. During the
first render, the DOM nodes have not yet been created, so ref.current will be null. And during the rendering of updates,
the DOM nodes haven’t been updated yet. So it’s too early to read them.

React sets ref.current during the commit. Before updating the DOM, React sets the affected ref.current values to null.
After updating the DOM, React immediately sets them to the corresponding DOM nodes.

Refs are an escape hatch. You should only use them when you have to “step outside React”. Common examples of this
include managing focus, scroll position, or calling browser APIs that React does not expose.
If you stick to non-destructive actions like focusing and scrolling, you shouldn’t encounter any problems. However,
if you try to modify the DOM manually, you can risk conflicting with the changes React is making.
To illustrate this problem. Take two buttons, the first button toggles its
presence using conditional rendering and state, as you would usually do in React. The second button uses the remove()
DOM API to forcefully remove it from the DOM outside of React’s control. After you’ve manually removed the DOM element,
trying to use setState to show it again will lead to a crash. This is because you’ve changed the DOM, and React doesn’t
know how to continue managing it correctly. *Avoid changing DOM nodes managed by React*`
Loading