This article is translated by the front-end translation team and published at: github.com/bigo-fronte… Welcome to follow and reprint.

Advanced frontend Interview Topics with React

First of all, let me be clear that this article doesn’t teach you anything. This only organizes topics and ideas, with a brief summary of each topic and idea.

Directory:

  • Axios
  • Lazyload
  • Error Boundaries
  • Webworker
  • IndexDB
  • Tokens, cookies, and JWT
  • Performance check
  • PWA
  • The real time
  • CSS properties
  • Higher-order Hooks
  • React memo
  • TDD
  • Big lists

Axios

If you know about axios security, it’s good that someone asked; If you don’t know, reveal plot warning, this problem was solved long ago.

Solution: github.com/axios/axios…

An alternative to Axios is the Request library or Fetch API (but there are some problems with that, too, because a failed status code is not passed to a catch, but instead is processed by a THEN, requiring additional steps such as Response.json (), No interceptors or anything else that would make Axios and other libraries easier to use).

Lazyload

Code splitting is a technique supported by packers such as Webpack, Rollup, and Browserify (fact-Bundle) to create multiple bundles and load them dynamically at run time.

How to achieve:

Functions can be imported dynamically:

import("./math").then(math= > {
  console.log(math.add(16.26));
});
Copy the code

Or the component can use react. Lazy:

const OtherComponent = React.lazy(() = > import('./OtherComponent'));
Copy the code

This code will automatically import the bundle containing the OtherComponent when the component is first rendered. Lazy components should then be rendered in Suspense components so that we can gracefully degrade them (loading indicators, etc.) while waiting for them to load.

const OtherComponent = React.lazy(() = > import('./OtherComponent'));
const AnotherComponent = React.lazy(() = > import('./AnotherComponent'));

function MyComponent() {
  return (
    <div>
      <Suspense fallback={<div>Loading...</div>} ><section>
          <OtherComponent />
          <AnotherComponent />
        </section>
      </Suspense>
    </div>
  );
}
Copy the code

This component can be used as a placeholder component. Examples of Semantic libraries: semantic-ui.com/elements/pl…

Error Boundaries

The error boundary is a React component that catches JavaScript errors that occur anywhere in the child component tree and prints those errors while displaying the degraded UI without rendering the child component tree that crashed. Error bounds catch errors during rendering, in lifecycle methods, and in constructors throughout the component tree.

class ErrorBoundary extends React.Component {
  constructor(props) {
    super(props);
    this.state = { hasError: false };
  }

  static getDerivedStateFromError(error) {
    // Update state so that the next rendering can display the degraded UI
    return { hasError: true };
  }

  componentDidCatch(error, errorInfo) {
    // You can also report error logs to the server
    logErrorToMyService(error, errorInfo);
  }

  render() {
    if (this.state.hasError) {
      // You can customize the degraded UI and render it
      return <h1>Something went wrong.</h1>;
    }

    return this.props.children; }}Copy the code

You can then use it as a regular component:

<ErrorBoundary>
  <MyWidget />
</ErrorBoundary>
Copy the code

Webworker

Using Web Workers, a Web application can run a scripted operation in a background thread independent of the main thread. This has the advantage of being able to perform time-consuming processing tasks in a separate thread, allowing the main thread (usually the UI thread) not to block/slow down as a result.

var w;
function startWorker() {
  if (typeof(Worker) ! = ="undefined") {
    if (typeof(w) == "undefined") {
      w = new Worker("demo_workers.js");
    }
    w.onmessage = function(event) {
      document.getElementById("result").innerHTML = event.data;
    };
  } else {
    document.getElementById("result").innerHTML = "Sorry! No Web Worker support."; }}function stopWorker() {
  w.terminate();
  w = undefined;
}
Copy the code

IndexDB

IndexDB is a built-in database that is much more powerful than localStorage. Key/ Value storage: A value can be (almost) anything, with multiple Key types. Support transactions to ensure reliability. Supports key range query and index. Can store much more data than localStorage.

See the sample

Tokens, cookies, and JWT

To do the authentication token process, we need to obtain two tokens: the Access token and the Session token. The key to maintaining access status is the Access token. It just gives us access to receive session tokens. After a period of time, this session token will expire in the back end. In this case, we need to send a new request with the Access token to refresh the session token. Typically, the server sends a 401 status code indicating that it is not authorized.

Using cookies makes the process much easier. When setting the request header, add the “credentials” attribute and assign the value to hidden cookies. These cookies should be set to not be overwritten by JS scripts, and Chrome will hide them in the cookies TAB.

Also: If you have CORS problems accessing the server, you should set the Access-Control-allow-Origin and/or access-Control-allow-headers attribute.

JSON Web Tokens (JWTs) makes it easier to send read-only signed “claims” between servers, both internal and external services. Claims can be any piece of data that you want other people to read and verify, but cannot change.

Performance check

  • Audits: Lighthouse is an open source automated tool that improves the quality of network applications. You can run it as a Chrome extension or from the command line. You provide Lighthouse with a site to review, which runs a series of tests against the page, and then generates a report on the performance of the page.
  • Redux DevTools: Redux DevTools is used to debug application state changes.
  • React DevTools: React DevTools allows you to examine the React component hierarchy in Chrome developer Tools. You’ll see two new tabs in Chrome DevTools: “⚛️ Components (view component tree)” and “⚛️ Profiler (Perform performance tests on each component)”. React DevTools also tells you how many times your component has been rendered.
  • Performance DevTools: Performance is a TAB in the developer tools that allows you to check the overall Performance of your application.
  • Network DevTools: You can view a list of all requests and track how long it takes to resolve them. Why-this-render: library that checks the number of component renders.
  • Renderer devTools: Renderer is an option in the developer tools console that allows you to track rendering information. FPS is one of the pieces of information to track, and it tells you how smooth your page is. The best number is 60. So, if you’re below that, it means your performance still needs to improve.

Other articles: Devtools, React Performance, and Profiler.

PWA

Progressive Web applications (PWAs) are web software applications built using common web technologies, including HTML, CSS, and JavaScript. The goal of PWAs is to run on any platform that uses a standard browser. Features include offline, push notifications, hardware access, and a user experience similar to native apps on the desktop and mobile. Because PWAs is a web site, or web App, it does not need to be installed on App distribution platforms such as Apple’s App Store or Google Play for developers or users. PWAs relies on manifests, which contain some basic information for applications, and Service workers, a category of Web workers. A service worker is basically a JavaScript file, independent of the main thread of the browser, which can intercept network requests, cache and obtain resources, and push messages.

The real time

As described in the RFC 6455 specification, the WebSocket protocol provides a way for the browser and server to exchange data over a persistent connection. The data is transferred in both directions as “packets” without breaking the connection or making additional HTTP requests. WebSocket is a great choice for services that require continuous data exchange, such as online games, real-time trading systems, etc.

// First create the connection
let socket = new WebSocket("wss://javascript.info/article/websocket/demo/hello");
// Here you register an action when the connection starts
socket.onopen = function(e) {
  alert("[open] Connection established");
  alert("Sending to server");
  socket.send("My name is John");
};
// When the socket is updated
socket.onmessage = function(event) {
  alert(`[message] Data received from server: ${event.data}`);
};
// When it closes
socket.onclose = function(event) {
  if (event.wasClean) {
    alert(`[close] Connection closed cleanly, code=${event.code} reason=${event.reason}`);
  } else {
    // e.g. server process killed or network down
    // event.code is usually 1006 in this case
    alert('[close] Connection died'); }};// And when some error happens
socket.onerror = function(error) {
  alert(`[error] ${error.message}`);
};
Copy the code

The Server send event specification has a built-in EventSource class that maintains a connection to the server and allows events to be received from the server. Similar to WebSocket, connections are persistent.

But EventSource differs from WebSocket in several important ways:

By comparison, EventSource is slightly weaker than WebSocket in communicating with the server.

let eventSource = new EventSource("/events/subscribe");
eventSource.onmessage = function(event) {
  console.log("New message", event.data);
  // will log 3 times for the data stream above
};

// or eventSource.addEventListener('message', ...)
Copy the code

Five ways to build real-time applications using JavaScript

CSS properties

  • Don’t use CSS ICONS, use SVG.
  • Use a separate selector, for exampleclassIs faster than using complex selectors such as descendant selectors.
  • Fewer elements count less at run time, so use child elements directly or a separate selector when you need them.
  • Alphabetical order (plug-ins or dependencies can handle this)
  • Don’t use extends (SASS) when you can use mixins
  • Shrink CSS code
  • Split CSS imports, referenced above elements that use those CSS. Componentization based on CSS.

The following video sums it up nicely:

Video source

Animation:

Watch the following video to see how CSS animations are triggered as listed above: youtu.be/0Xg6r_MKGJ4

Higher-order Hooks

UseMemo returns a memoized value. Pass in the create function and an array of dependencies as arguments. It recalculates the Memoized value only when a dependency changes. This optimization helps avoid costly calculations every time you render. Remember that functions passed into useMemo are executed during rendering. Please do not perform non-rendering operations inside this function. Operations such as side effects are used by useEffect, not useMemo. If the dependency array is not provided, useMemo evaluates the new value each time it renders.

const memoizedValue = useMemo(() = > computeExpensiveValue(a, b), [a, b]);
Copy the code

The useLayoutEffect function has the same signature as useEffect, but it calls Effect synchronously after all DOM changes. You can use it to read DOM layouts and trigger rerenders synchronously. The update schedule inside useLayoutEffect is refreshed synchronously before the browser performs the drawing. Use standard Useeffects whenever possible to avoid blocking visual updates.

UseReducer is an alternative to useState. It receives a Reducer of the form (state, action) => newState and returns the current state and its accompanying dispatch method. (If you’re familiar with Redux, you already know how it works.)

UseReducer can be more useful than useState in some situations, such as when the state logic is complex and contains multiple subvalues, or when the next state depends on the previous state. Also, using useReducer can optimize performance for components that trigger deep updates because you can pass dispatches to child components instead of callbacks.

Here is an example of a counter that overwrites the useState section with reducer:

const initialState = {count: 0};
function reducer(state, action) {
  switch (action.type) {
    case 'increment':
      return {count: state.count + 1};
    case 'decrement':
      return {count: state.count - 1};
    default:
      throw new Error();
  }
}
function Counter() {
  const [state, dispatch] = useReducer(reducer, initialState);
  return (
    <>
      Count: {state.count}
      <button onClick={()= > dispatch({type: 'decrement'})}>-</button>
      <button onClick={()= > dispatch({type: 'increment'})}>+</button>
    </>
  );
}
Copy the code

React memo

React Memo is a high-level component that basically checks if the component should be rerendered. If some changes are indeed received, it is possible to prevent child components from re-rendering unnecessarily while the parent component is re-rendering.

Watch the video to learn more about React Memo

You can export components in the following ways:

export default React.memo(ComponentName)
Copy the code

TDD

Test-driven Development is an application approach to the software Development process that relies on the repetition of very short Development cycles: translating requirements into very specific Test cases, and then optimizing the software to pass testing.

Big lists

If you have a list of thousands of items to show, but don’t want to degrade the user experience on mobile, this video gives you two options for dealing with the situation: www.youtube.com/watch?v=QhP…

I’m particularly grateful for all the resources that have been applied to this article, such as w3schools, javascript. Info, MDN, react documentation, and several videos from Youtube.

Bye 😀

Twitter: twitter.com/danilodev Github: github.com/danilosilva… Twitch: www.twitch.tv/gorickisnot…

Welcome everyone to leave a message to discuss, wish smooth work, happy life!

I’m bigO front. See you next time.