Magren

Magren

Idealist & Garbage maker 🛸
twitter
jike

About Github Report 👨‍🚀

Preface 🛸#

GitHub is a software source code hosting platform that uses Git for version control. It was developed by Chris Wanstrath, P. J. Hyett, and Tom Preston-Werner of GitHub (formerly known as 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 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 assignments. Previously, I used Puppeteer to try to scrape some data from GitHub, and then I had a crazy idea and decided to combine it with the backend I had previously written and use React functional components to create a page to display some data from a person's GitHub.

Project link: Github Report

login.png
welcome.png
repinfo.png
contributions.png

NES.css 🚀#

NES, also known as the "Red and White Machine," was introduced to China in the late 1980s and early 1990s and was the first game console that the post-80s generation had contact with. NES.css is a CSS framework that mimics the style of NES (8-bit console) and is a pixelated CSS component library. It does not have any JavaScript dependencies and only includes CSS.

The component styles provided by NES.css are very appealing to me, and it also provides some fun pixelated icons. By default, NES.css only has pixelated styles for English fonts. If you need pixelated styles for other languages, 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 has a height of 100vh, and after hiding the scroll bar, I listen for mouse scrolling (or touch on mobile). The scrolling method is to slide the entire page up or down by 100vh (using margin-top to hide the excess and setting a transition for animation effects). At the same time, I implemented throttling using a timestamp (to execute a method only once within a certain time period) to prevent frequent scrolling by the user. Here is an example:

function throttle(event, time) {
  let pre = 0;
  return function (...args) {
    if (Date.now() - pre > time) {
      pre = Date.now();
      event.apply(this, args);
    }
  }
}

The effect was there, but it felt a bit ordinary 🤨. Then, while browsing the React-spring documentation, I came across Parallax. Parallax allows you to create a scrollable container and use ParallaxLayer to contain content. You can set the offset and speed of ParallaxLayer, creating a parallax scrolling effect (where many elements on the page scroll independently of each other). I thought it looked great, so I immediately adopted it 😆.

I have seen examples online that use background-attachment (to fix the background image position within the viewport or scroll with the containing block) and transform (to adjust the scroll distance using translateZ). 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 frequently use.

useState#

useState is used to introduce state into functional components. This function returns an array, where the first element is the variable and the second element is a method used to modify the variable. For example:

// Declare a state variable named "count"
const [count, setCount] = useState(0);

useEffect#

useEffect replaces the componentDidMount, componentDidUpdate, and componentWillUnmount lifecycle methods. It 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 when sharing state between components without passing props explicitly through the component tree. Here is an example:

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 deeper 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, with its .current property initialized to the passed argument (initialValue).

The returned ref object persists for the entire lifecycle of the component, similar to an instance property in 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 (not inside loops, conditions, or nested functions).
  • ✅Only call Hooks from React functional components.
  • ✅Only call other Hooks from custom Hooks.

These are the rules mentioned in the React Hook documentation. The reason is that React does not actually store state internally; it tracks state through the order of calls.

In other words, multiple useState calls are maintained through a linked list, and multiple states are identified by indexes. If Hooks are called inside an if/else statement, the call order may change when the function component is re-executed, leading to errors.

This process is as follows:

  • During the first render, state is declared one by one according to the order of useState calls and added to the global array. Each state declaration increases the cursor by 1.
  • Whenever a state event is triggered, the corresponding state value in the state array is modified, triggering a re-render. The cursor is reset to 0. The latest state values are retrieved one by one according to the order of useState declarations, and the view is updated.

Finally 🔭#

Thanks to NES.css and React-spring 🙏

This is a personal learning project that I came up with on a whim. If there are any areas for improvement or bugs, feel free to discuss 🙌

If this can help you learn something, it would be my honor 🔮

Loading...
Ownership of this post data is guaranteed by blockchain and smart contracts to the creator alone.