Preface🛸#
GitHub is a software source code hosting service platform that uses Git for version control. It was developed by Chris Wanstrath, P. J. Hyett, and Tom Preston-Werner of GitHub (formerly Logical Awesome) using Ruby on Rails. As of January 2020, GitHub has over 40 million registered users and 190 million code repositories (including at least 28 million open-source code repositories), making it the largest code hosting website and open-source community in the world.
As the largest open-source community in the world, GitHub plays a crucial role in my programming learning. I have used it to copy other people's code to get through homework crises. Previously, I used Puppeteer to try to crawl some data from GitHub, and then my brain went blank, and I decided to use the backend I had previously written and combine it with React functional components to create a page to display some data from a person's GitHub.
Project link: Github Report
NES.css🚀#
NES, which entered China in the late 1980s and early 1990s, is the earliest game console that 80s generation in China came into contact with. It is commonly known as the "red and white machine". It is a game console that uses an 8-bit processor. NES.css is a CSS framework that imitates the style of NES (8-bit console) and is also a pixel-style CSS component library. It does not have any JavaScript dependencies and only includes CSS.
The component styles provided by NES.css are very much to my liking, and it also provides some fun pixel icons. In the default settings of NES.css, only the English font is in pixel style. If you need other languages to be in pixel style, you need to download the fonts yourself.
👀For specific usage, please refer to the official documentation: NES.css
React-spring🌏#
From the very beginning, I wanted to create a full-page scrolling effect. Each of my pages is 100vh, and after hiding the scroll bar, I listen for mouse scrolling (or touch scrolling on mobile). The scrolling method is to slide the entire page up or down by 100vh (using margin-top to hide the excess part and setting transition to create an animation effect). At the same time, I implemented throttling using a timestamp (execute a method only once within a certain time period) to prevent frequent scrolling by the user.✍:
function throttle(event, time) {
let pre = 0;
return function (...args) {
if (Date.now() - pre > time) {
pre = Date.now();
event.apply(this, args);
}
}
}
The effect is there, but it feels a bit ordinary🤨. Then I flipped through the React-spring documentation and saw Parallax, which can create a scrollable container and use ParallaxLayer to contain content. It can also set the offset and speed, creating a parallax scrolling effect (many elements on the page scroll independently of each other). I thought it looked good, so I immediately adopted it😆.
I have seen examples online that use background-attachment (whether the background image is fixed within the viewport or scrolls with the containing block) and transform (by setting translateZ, the scrolling distance is different) to achieve this effect. However, in React-spring, Parallax is implemented using JavaScript by listening for scrolling and dynamically setting the position using translate🤔.
I need to take a closer look when I have time. The documentation is here👉: React-spring
React Hook📡#
Since I am using functional components in React, I cannot avoid using its hook functions. Here are a few that I often use.
useState#
Introduces state to functional components. This function returns an array, where the first element is the variable and the second element is a method used to change the variable. For example:
// Declare a state variable named "count"
const [count, setCount] = useState(0);
useEffect#
The useEffect hook function can be said to replace the componentDidMount, componentDidUpdate, and componentWillUnmount lifecycle methods. useEffect() is also executed when the component is first rendered. Here is an example✍:
useEffect(
// Equivalent to componentDidMount
() => {
// Equivalent to componentWillUnmount
return () => {
};
},
// Dependency list, useEffect() will be executed when these dependencies change, equivalent to componentDidUpdate
[]
);
useContext#
useContext() is used in cases where components need to share state without explicitly passing props through the component tree.
const themes = {
light: {
foreground: "#000000",
background: "#eeeeee"
},
dark: {
foreground: "#ffffff",
background: "#222222"
}
};
const ThemeContext = React.createContext(themes.light);
function App() {
return (
<ThemeContext.Provider value={themes.dark}>
<Toolbar />
</ThemeContext.Provider>
);
}
// Child component
function Toolbar(props) {
return (
<div>
<ThemedButton />
</div>
);
}
// Grandchild or more nested component
function ThemedButton() {
const theme = useContext(ThemeContext);
return (
<button style={{ background: theme.background, color: theme.foreground }}>
I am styled by theme context!
</button>
);
}
useRef#
useRef returns a mutable ref object, whose .current property is initialized to the passed argument (initialValue).
The returned ref object persists for the entire lifetime of the component, similar to an instance property of a class. It can conveniently store any mutable value.
function TextInputWithFocusButton() {
const inputEl = useRef(null);
const intervalRef = useRef();
const onButtonClick = () => {
// `current` points to the mounted text input element
inputEl.current.focus();
};
useEffect(
() => {
const id = setInterval(() => {
// ...
});
intervalRef.current = id;
return () => {
clearInterval(intervalRef.current);
};
});
return (
<>
<input ref={inputEl} type="text" />
<button onClick={onButtonClick}>Focus the input</button>
// ...
</>
);
}
Warning 🔒#
- ✅Only use Hooks at the top level (do not use them inside loops, conditions, or nested functions).
- ✅Call Hooks only in React functional components.
- ✅Call other Hooks only in custom Hooks.
These are the rules in the React Hook documentation, because React does not actually store state internally. It tracks state by the order of calls.
In other words, multiple calls to useState are maintained by a linked list, and multiple states are identified by indexes. If Hooks are called in an if/else statement, the call order may change when the function component is re-executed, resulting in errors.
This process:
- During the first render, state is declared one by one according to the order of useState and added to the global array. Each time state is declared, the cursor is incremented by 1.
- Each state event has a corresponding cursor value. When any state event is triggered, the corresponding state value in the state array is modified, triggering a re-render. The cursor is reset to 0. According to the order of useState declarations, the latest state values are taken out one by one, and the view is updated.
Finally🔭#
Thanks to NES.css and React-spring🙏
This is a personal project that I impulsively started to learn. If there are any improvements or bugs, feel free to discuss🙌
If this thing can help you learn something, it would be my honor🔮