본문 바로가기

React

React 앱에서 파일 시스템 접근 API 활용하기

React 앱에서 사용자 파일에 직접 접근할 수 있다면 기능 확장이 무궁무진합니다. 파일 시스템 접근 API(File System Access API)는 브라우저가 지원하는 최신 API로, 사용자 로컬 파일을 읽고 저장할 수 있게 해줍니다. 이번 글에서는 React와 함께 파일 시스템 접근 API를 활용하는 방법을 실무 중심으로 소개합니다.

1. 파일 시스템 접근 API란?

파일 시스템 접근 API는 웹 앱이 사용자의 로컬 파일과 폴더를 직접 읽고 쓸 수 있도록 하는 최신 웹 표준 API입니다. 기존에 파일 입력 창으로 제한되던 사용자 파일 접근 권한을 확장해 앱의 편의성과 기능성을 크게 향상시킵니다.

2. React에서 파일 열기 구현하기

파일 열기 기능은 window.showOpenFilePicker() 함수를 이용해 구현합니다. 선택된 파일은 File 객체로 변환되어 React 상태로 관리할 수 있습니다.

const [fileContent, setFileContent] = React.useState("");

const openFile = async () => {
  try {
    const [fileHandle] = await window.showOpenFilePicker();
    const file = await fileHandle.getFile();
    const text = await file.text();
    setFileContent(text);
  } catch (error) {
    console.error('파일 열기 실패:', error);
  }
};

3. React에서 파일 저장 구현하기

사용자가 데이터를 편집한 뒤 로컬에 저장할 수 있도록 window.showSaveFilePicker()를 사용해 저장 기능을 구현합니다.

const saveFile = async (content) => {
  try {
    const fileHandle = await window.showSaveFilePicker({
      types: [{
        description: '텍스트 파일',
        accept: { 'text/plain': ['.txt'] },
      }],
    });

    const writable = await fileHandle.createWritable();
    await writable.write(content);
    await writable.close();

    alert('파일 저장 완료');
  } catch (error) {
    console.error('파일 저장 실패:', error);
  }
};

4. 상세 예제: 텍스트 파일 에디터 만들기

아래는 React 컴포넌트로 작성한 간단한 텍스트 파일 열기 및 저장 에디터 예제입니다.

import React, { useState } from 'react';

function FileEditor() {
  const [content, setContent] = useState("");

  const handleOpen = async () => {
    try {
      const [fileHandle] = await window.showOpenFilePicker();
      const file = await fileHandle.getFile();
      const text = await file.text();
      setContent(text);
    } catch (e) {
      console.error(e);
    }
  };

  const handleSave = async () => {
    try {
      const fileHandle = await window.showSaveFilePicker({
        types: [{
          description: 'Text Files',
          accept: { 'text/plain': ['.txt'] },
        }],
      });
      const writable = await fileHandle.createWritable();
      await writable.write(content);
      await writable.close();
      alert('파일이 저장되었습니다.');
    } catch (e) {
      console.error(e);
    }
  };

  return (