Handle DOM in React - JeongWu/fe-javascript GitHub Wiki

Handle DOM in React

ref

render ๋ฉ”์„œ๋“œ์—์„œ ์ƒ์„ฑ๋œ DOM ๋…ธ๋“œ๋‚˜ React ์—˜๋ฆฌ๋จผํŠธ์— ์ ‘๊ทผ

  • animation ์ œ์–ด๋ฅผ ํ•ด์•ผํ•  ๋•Œ
  • focus,text, media ์„ ํƒ ์ œ์–ด๊ฐ€ ํ•„์š”ํ•  ๋•Œ(DOM API ํ˜ธ์ถœ์„ ํ•ด์•ผํ•  ๋•Œ)
  • ์™ธ๋ถ€ DOM Library ์‚ฌ์šฉํ•  ๋•Œ

์‚ฌ์šฉ

  • const myRef=react.createRef()๋ฅผ ํ†ตํ•ด ์ƒ์„ฑ
  • ref ์†์„ฑ์„ ํ†ตํ•ด ์ฐธ์กฐ๋ฅผ ์„ค์ •
const TextInput = () => {
  const textInput = useRef(null);

  const focusInput = () => {
    textInput.current.focus();
  }

  return (
    <div>
      <input
        type="text"
        ref={textInput}
      />
      <button onClick={focusInput}>
        Focus
      </button>
    </div>
  );
}

export default TextInput;

Portal

๋ถ€๋ชจ ์ปดํฌ๋„ŒํŠธ์˜ ๋ฐ”๊นฅ์— DOM ๋…ธ๋“œ๋กœ ์ž์‹์„ ๋ Œ๋”๋ง

  • modal, tooltip, ์™ธ๋ถ€ layer ๋“ฑ

์‚ฌ์šฉ

ReactDOM.createPortal(child: React.ReactNode, container: HTMLElement)
react root DOM node ์™ธ๋ถ€์— React Element ๊ทธ๋ฆฌ๊ธฐ

const Modal = () => {
  return ReactDOM.createPortal(
    <div>I am a modal</div>,
    document.body.querySelector('#app')
  )
}

const App = () => {
  const [count, setCount] = React.useState(0);

  return (
    <div onClick={() => setCount(count + 1)}>
      <div>Hello!</div>
      <div>count: {count}</div>
      <Modal />
    </div>
  )
}

export default App

Context

์•ฑ ์ „์ฒด์—์„œ ์—ฌ๋Ÿฌ๊ตฐ๋ฐ์—์„œ ์‚ฌ์šฉ๋˜๋Š” ๊ฐ’(global value)์„ ์ƒ์œ„์—์„œ ์ „๋‹ฌํ•˜๋Š” ๋ฐฉ๋ฒ•

์‚ฌ์šฉ

  • React.createContext(defaultValue); ํ†ตํ•ด Context ๊ฐ์ฒด๋ฅผ ์ƒ์„ฑ
  • <Context.Provider value={contextValue}> ๋ฅผ ํ†ตํ•ด context ์ฃผ์ž…
  • ํ•˜์œ„ ์–ด๋Š component์—์„œ๋ผ๋„ useContext(Context) ํ†ตํ•ด contextValue ํš๋“๊ฐ€๋Šฅ
  • context ์‚ฌ์šฉ x
function App() {
  return <Toolbar theme="green" />;
}

function Toolbar({ theme }) {
  return (
    <div>
      <ThemedButton theme={theme} />
    </div>
  );
}

const ThemedButton = ({ theme }) => (
  <button className={`button-${theme}`}>
    button
  </button>
)

export default App;
  • context ์‚ฌ์šฉ
const ThemeContext = createContext('green');

function App() {
  return (
    <ThemeContext.Provider value="blue">
      <Toolbar />
    </ThemeContext.Provider>
  );
}

function Toolbar() {
  return (
    <div>
      <ThemedButton />
    </div>
  );
}

const ThemedButton = () => {
  const theme = useContext(ThemeContext) //import themeprovider์˜ value๊ฐ’ ๋ฐ›์•„์˜ด
  return (
    <button className={`button-${theme}`}>
      button
    </button>
  )
}

export default App;

Error Boundaries

Error: React App ์ „์ฒด๋ฅผ unmount

class component

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

  static getDerivedStateFromError(error) {
    // Update state so the next render will show the fallback UI.
    return { hasError: true };
  }

  componentDidCatch(error, info) {
    // You can also log the error to an error reporting service
    logErrorToMyService(error, info);
  }

  render() {
    if (this.state.hasError) {
      // You can render any custom fallback UI
      return <h1>Something went wrong.</h1>;
    }

    return this.props.children;
  }
}
<ErrorBoundary>
  <MyWidget />
</ErrorBoundary>

React ๋ฐฉ์‹์œผ๋กœ ์‚ฌ๊ณ ํ•˜๊ธฐ

  • Mock ์ค€๋น„
  • ํ™”๋ฉด์„ ๋‚˜๋ˆ ์„œ ์ปดํฌ๋„ŒํŠธ ๋งŒ๋“ค๊ธฐ
  • ์ •์ (static) ๋ฒ„์ „ ๋งŒ๋“ค๊ธฐ
โš ๏ธ **GitHub.com Fallback** โš ๏ธ