WebDevCurriculum]Reactベースのファイルシステム実装-txt/imageの読み込み


1.概要


既存のVanillaJSを使用してファイルシステムを実装するのと比較して、Reactベースのファイルシステムにはどのような利点がありますか?

2.コア

  • ファイルをローカルシステムから読み取り、ステータス変数に変換して、ファイルをすぐにロード(反映)します.
  • react-router-domはバージョン6に更新され、propsは使用できないため、localStorageを使用してデータストレージを構成します.
  • 3.全体ロジック


    ユーザーがログインすると、ログイン情報に基づいてデータがメンテナンスおよびロードされます.
  • ユーザ入力ID、PW登録.
  • にログインして、別のページ(Detail)に移動します.
  • Detailページでは、ユーザIDなどを使用してデータをロードおよび維持します.

  • 4-1. App.js-ルーティング構造構成


    ルーティング構造を構成する.
  • React-Ruter-domバージョンのアップグレードの遵守事項に従ってルーティングを構成します.
  • ルータ(最上位ルーティングレイヤ)、ルーティング、およびルーティングからなり、各ルーティングはルーティングコンポーネントに含まれる必要があります.
  • import React from 'react';
    import { BrowserRouter as Router, Routes, Route } from 'react-router-dom';
    import Home from '../routes/Home.js';
    import Detail from '../routes/Detail.js';
    
    function App() {
      return (
        <Router>
          <Routes>
            <Route path="/" exact={true} element={<Home/>} />
            <Route path="/:userID" element={<Detail/>}/>
          </Routes>
        </Router>
      );
    }
    
    export default App;

    4-2. Home.js-ユーザーデータ入力とローカルストレージデータ転送


    localStorageを一時リポジトリとして使用して、ユーザーが入力したデータを渡します.
  • ここでの核心は、入力データを受信し、データの変化(イベント検出など)に直ちに応答できるように状態管理することである.
  • VanillaJSとは異なり,
  • Reactはコンポーネント内部で状態値を関数パラメータとして利用できる.
  • ユーザーステータスを使用して、ステータス管理宣言>入力データ(値)をステータス変数
  • に保存します.
  • propsでコンポーネント間でデータを転送できないため、localStorageを一時データとして格納します.
  • const [userID, setUserID] = useState('');
    const [userPW, setUserPW] = useState('');
    
    setUserID(value);
    setUserPW(value);
    
     <input type='text' placeholder="ID" value={userID} onChange={updateUserID}/>
     <input type='password' placeholder="PW" value={userPW} onChange={updateUserPW}/>
       
       
    <Link to={{
                    pathname: `/${userID}`
                }} onClick={() => saveStateValues(userID, userPW)}>로그인하기</Link>
    Home.jsの完全な構成
    import React, {useState} from 'react';
    import {Link} from 'react-router-dom';
    import {gql, useQuery} from '@apollo/client';
    import styled from 'styled-components';
    
    const dataContext = React.createContext();
    
    const Container = styled.div`
    `
    
    const Title = styled.h1`
        padding: 1%;
        align-items: center;
    `
    
    const UserInformation = styled.div`
        display: flex;
    `
    
    function Home() {
    
        const [userID, setUserID] = useState('');
        const [userPW, setUserPW] = useState('');
    
        const updateUserID = e => {
            const {target : {value}} = e;
            //value 변수 자체는 문자 하나하나
            //각각 입력될때마다 반응
    
            setUserID(value);
            //이 입력되는 값들에 대해
            //상태관리화하면 (누적된) 상태관리가 가능해진다.
            console.log(userID);
        };
    
        const updateUserPW = e => {
            const {target : {value}} = e;
            //value 변수 자체는 문자 하나하나
            //각각 입력될때마다 반응
    
            setUserPW(value);
            //이 입력되는 값들에 대해
            //상태관리화하면 (누적된) 상태관리가 가능해진다.
            console.log(userPW);
        };
        
        const saveStateValues = (userID, userPW) => {
            localStorage.setItem(userID, userPW);
        };
    
        return(
            <Container>
                <Title>사용자 로그인</Title>
                <UserInformation>
                    <input type='text' placeholder="ID" value={userID} onChange={updateUserID}/>
                    <input type='password' placeholder="PW" value={userPW} onChange={updateUserPW}/>
                </UserInformation>
                <Link to={{
                    pathname: `/${userID}`
                }} onClick={() => saveStateValues(userID, userPW)}>로그인하기</Link>
            </Container>
        )
    };
    
    export default Home;
    活動を組織するときは、記入形式に注意しなければならない.
    転送
  • onClick={()=>関数()}→イベントパラメータ、例えば
  • onClick={function()}→イベントパラメータは一緒に渡されません.
  • 4-3. Detail.js-画面切り替え後のデータ受信、メンテナンス、ロード


    データストアやフックなどで従来のコンポーネントからデータを受信する.
  • ユーザIDは、URLを介して伝達される.
  • ユーザPWはlocalStorageを介して送信される.
  • デフォルトでは、ローカルファイルシステムにデータが入力され、ステータス管理が行われます(最終的に受信したテキスト/画像データに対してStateを使用します).
  • 状態変数を戻り値に適用すると,直ちにデータを反映することができる.
  • const {userID} = useParams();
    const userPW = localStorage.getItem(userID);
    //const userIDByLocal = localStorage.key(userPW);
    
    const [finalText, setFinalText] = useState('');
    const [finalImage, setFinalImage] = useState('');
    
    let txtDATA = localStorage.getItem(`${userID}fortxt`);
    let imageDATA = localStorage.getItem(`${userID}forimg`);
    
    setFinalText(text);
    setFinalImage(fileRead.result);
    
    {finalText? (<pre className="textArea" contentEditable>{finalText}</pre>) : (<div>NO SAVED TEXT DATA</div>)}
    {finalImage? (<div className="imageAreaCover"><img className="imageArea" src={finalImage}></img></div>) : (<div>NO SAVED IMAGE DATA</div>)}
    ※file system(外部入出力)でデータを転送中は、直ちにステータス管理が適用されません.
    ※最終入力text/image fileのデータを状態管理変数に入れ、return(画面実装)に使用します.
    Detail.jsの完全な構成
    import React, {useState} from 'react';
    import { useParams } from 'react-router';
    import styled from 'styled-components'
    
    //import {useRef} from 'react-router-dom';
    
    let fileRead = new FileReader();
    
    const Container = styled.div`
    `
    
    function Detail(){
    
        const {userID} = useParams();
        const userPW = localStorage.getItem(userID);
        //const userIDByLocal = localStorage.key(userPW);
    
        const [finalText, setFinalText] = useState('');
        const [finalImage, setFinalImage] = useState('');
    
        let txtDATA = localStorage.getItem(`${userID}fortxt`);
        let imageDATA = localStorage.getItem(`${userID}forimg`);
    
        let fileBuffer = null;
    
        async function fileOpenButton(){
            [fileBuffer] = await window.showOpenFilePicker();
            
            let fileData = await fileBuffer.getFile();
            console.log(fileData);
        
            if(fileData.type !== 'image/png'){
                //interface file data
                //await fileRead.readAsDataURL(fileData)
                let text = await fileData.text();
                localStorage.setItem(`${userID}fortxt`, text)
    
                setFinalText(text);
                return ;
        
            }else if(fileData.type == 'image/png' || 'image/jpeg'){
                //fileReader가 fileData를 먼저 읽어야 한다.
                await fileRead.readAsDataURL(fileData);
                fileRead.addEventListener('load', () => {
                    localStorage.setItem(`${userID}forimg` , fileRead.result);
                    setFinalImage(fileRead.result);
                    //console.log(fileRead.result);
                    //console.log(imageArea.src);
                    })
                
                
                return;
    
                
    
                //fileRead - null, fileRead.result - image URL.
                //upload event를 부여할 경우에만 fileRead에서 data를 읽어올 수 있다.
                
            }else{
                return;
            }
        };
    
        return(
            <Container>
                <button className="fileOpen" type="file" onClick={fileOpenButton}>파일 불러오기</button>
                {finalText? (<pre className="textArea" contentEditable>{finalText}</pre>) : (
                <div>NO SAVED TEXT DATA</div>)}
                {finalImage? (<div className="imageAreaCover"><img className="imageArea" src={finalImage}></img></div>) : (
                    <div>NO SAVED IMAGE DATA</div>)}
                <button className="fileSave">파일 저장하기</button>
                <button className="fileSaveAs">다른 이름으로 파일 저장하기</button>
            </Container>
        )
    }
    
    export default Detail;

    4-4. リファレンス


    個別のスクリーンレンダリングが必要な場合は、対応するコンポーネントを構成し、ブランチ処理で戻ります(スクリーン実装).

    5.参照リンク


    Reactイベントの処理
    https://ko.reactjs.org/docs/handling-events.html