2차 인터뷰를 앞두고, 다시한번 복습할 겸 리액트 정리.
1. Core React Concepts
React |
1. Core React Concepts
1) Components
function Name(props) {
return <div>{props.something}</div>;
}
* choosing between 'function' and 'const(arrow function)' comes down to personal preference and specific use cases. but using 'function' might be more straightforward and easy to read. 'const' is more recommended in 2024.
* In 2024, no need to learn Class Components due to React Hooks, which are used only in function components.
2) Hooks
https://react.dev/reference/react/hooks
Hooks let you use "hook into" react state and lifecycle features from function components.
to enable using state and other react features without writing a class component.
useState
lets you add state to your functional components.
lets component "remember" information. helps us keep track of things that can change in our app. like a "toy box"
declares a state variable that you can update directly
useEffect
lets you perform side effects in functional components.
lets a components connect to and synchronize with external systems. This includes dealing with network, browser DOM, animation, widgets written using a different UI library, and other non-React code.
useEffect connects a component to an external system.
"escape hatch" from the React paradigm. If you are not interacting with an external system, you might not need an Effect.
Common Use Cases for useEffect
1. Data Fetching (API Requests)
import React, { useEffect } from 'react';
const App = () => {
const [books, setBooks] = useState([]);
useEffect(() => {
fetchBooks();
}, []);
const fetchBooks = async () => {
try {
const response = await getBooks();
setBooks(response.data);
} catch (error) {
console.error('Error fetching books:', error);
}
};
useEffect(() => {
fetch('https://jsonplaceholder.typicode.com/users')
.then(response => response.json())
.then(data => setData(data));
}, []);
2. Setting Up Subscriptions
3. Updating Document Title
to update the document title based on some state or props.
4. Performing Cleanup
useContext
lets a component receive information from distant parents without passing it as props.
ex) a top-level component can pass the current UI theme to all components below, no matter how deep.
function Button() {
const theme = useContext(ThemeContext);
}
useRef
holds some information that isn't used for rendering, like a DOM node or a timeout ID.
useRef is useful when working with non-React systems, such as the built-in browser APIs.
function From() {
const inputRef = useRef(null);
// ...
Performance Hooks
useMemo
lets you cache the result of an expensive calculation
function TodoList({ todos, tab, theme }) {
const visibleTodos = useMemo(() => filterTodos(todos, tab), [todos, tab]);
// ...
}
useCallback
lets you cache a function definition before passing it down to an optimized component.
3) Lifecycle Methods
What causes React to render?
1. Initial Render: When a component is first mounted into the DOM.
2. State Changes: using 'useState', 'useReducer', or any other state management hooks.
3. Prop Changes: When the props passed to a component change, causing it to re-render.
4. Context Changes: When the context value provided by a 'Context.Provider' changes.
5. Force Update: using methods like 'forceUpdate'.
Lifting state up?
: A pattern where state is moved to a common ancestor or components that need to share this state. This avoids redundant state and ensures that changes propagate correctly.
Avoid prop drilling and overusing context
: Composition allows you to build components that can accept other components as props, making easier to share data and avoid prop drilling.
1. Create a Wrapper Component
that accepts children or components as props.
2. Use Composition in Parent Component
You can pass entire components as props, which reduces the need to drill down props through multiple layers. This keeps your codebase cleaner and more maintainable.
2. Advanced Topics
1) Error Boundaries
2) React Router
React Router - Router 6
TanStack Router
alternative, but React Router is good enough.
Next.js
for server-rendered React applications with flexible routing options.
3) Performance Optimization
Techniques like memoization
React.memo
useMemo
useCallback
code splitting
lazy loading
3. Ecosystem and Tools
1) State Management Libraries
Why we need a state management tool?
When we have to send the same data to lots of components or when components are far away from each other, passing props can be complicated. This can make an application slower and harder to work with.
built-in feature
Context API
https://react.dev/reference/react/createContext
https://www.freecodecamp.org/news/context-api-in-react/
function App() {
const [theme, setTheme] = useState('light')
return (
<ThemeContext.Provider value={theme}>
<Page />
</ThemeContext.Provider>
);
}
*prop drilling
to pass data down to the component, we need to pass it down through all the intermediate components, even if those components don't actually use the data themselves.
Prop drilling can make your code more difficult to read and maintain, and can also make it harder to refactor your components later on.
With Context API, you can store data at the top level of the component tree and make it available to all other components that need it without passing props.
Context API consists of two main components:
context provider (is responsible for creating and managing the context, which holds the data to be shared between components)
context consumer (is used to access the context and its data from within a component)
Use Case of Context API
- Theming
- User Authentication
- Multilingual Support
- Accessing data from external sources (APIs or data bases)
Redux
Redux Toolkit is an excellent choice for larger, complex, more structured applications
a centralized and declarative approach to state management.
Zustand
lightweight and flexible state management library designed for smaller projects or developers who prefer a more straightforward solution. It simplifies state management without the need for complex setup and concepts.
Recoil
Jotai
2) Styling
Material UI
Inflexible, hard to customize, and increate bundle size greatly.
TailwildCSS
It allows you to style your component with chainable, premade classes, in combination with a minimal component library, such as Radix.
ShadCN UI
A set of component that uses both TailwindCSS and Radix components and provides a good starting place for any application. You can also customize it more than a traditional component library.
3) Testing
Jest
React Testing Library
understanding the importance of unit
integration
end-to-end tests
Build Tools: Webpack, Vite, and create-react-app
Webpack: module bundler / when using next.js, no need to configure webpack.
TypeScript: Understanding how to use TypeScript with React for type safety
4. Practical Skills
1) Debugging
React Developer Tools (Chrome extension)
allows you to inspect the React component hieracrchy, view the state and props of components, and make changes to the component's state for testing.
Redux DevTools (Chrome extension)
2) Code Quality
Writing clean, maintainable, and reusable code
principles like DRY, KISS, and SOLID
3) System Design
Be prepared to discuss system design questions, especially for larger applications and state management.
5. Frequent React Interview Questions
1) How to pass data from child to parent
export function ParentComponent() {
const [dataFromChild, setDataFromChild] = useState(null);
const handleDataFromChild = (data) => {
setDataFromChild(data);
};
return (
<div>
<ChildComponent sendDataToParent = {handleDataFromChild} />
</div>
);
}
function ChildComponent(props) {
return (
<div>
<input ... onChange={(e) => props.sendDataToParent(e.target.value)} />
</div>
2) How to render an element outside of component scope/tree
createPortal
lets you render some children into a different part of the DOM.
https://react.dev/reference/react-dom/createPortal
3) How to implement code splitting in your React app and why?
lazy loading
lets you defer loading component's code until it is rendered for the first time.
to optimized the loading performance by splitting the code into smaller bundles that are loaded on demand.
lazy loading enforces code splitting of components
4) What is the best way to add a global store to your React app or project?
It depends on exactly what library the team wants to use for managing the global state.
Redux / Redux Toolkit
Zustand
5) Give me an example of a basic React SSR Implementation
Server-Side Rendering
for static website
generates the HTML on the server for each request.
if your site's content doesn't require much user interaction
it positively influences accessibility, page load times, SEO, and social media support
Next.js / Nuxt.js
Often used in dynamic web applications
Use Cases: e-learning websites, online marketplaces, applications with a straightforward user interface with fewer pages, features and dynamic data
Client-Side Rendering
if you are prioritizing the user experience
for cost-effective rendering for dynamic web app like social networks or online messengers.
Because these apps' information constantly changes and must deal with large and dynamic data to perform fast updates to meet user demand.
delivers a minimal HTML shell and using JavaScript to build the content dynamically in the browser.
Typically for SPAs.
React / Angular / Vue.js
Use Cases: SPAs (Gmail, Trello, Google Maps), Real-Time Applications(Slack, Twitter, Facebook's news feed), Interactive Dashboards and Data Visualization(Google Analytics, Financial dashboards), Progressive Web Apps(app-like experience, including offline capabilities, push notifications, and fast loading times, Starbucks PWA, Pinterest)
Complex Form Handling and User Interactions
(Online banking apps, e-commerce checkout processes, servey platforms)