反応基础クラス-3


Event Listener


ユーザーの動作(=イベント)
イベントリスナーは<div onClick={}>のようにエリー小屋に直接入れることができますが、addEventListenerで追加できます.
反応関数型ではuseEffect()反応フックを用いた.
リアクションフックは、ライフサイクル関数のコンポーネントDidMountとコンポーネントDidUpdateとコンポーネントWillUnmountの組み合わせです.React.useEffect(() => {}, []);構成部品をレンダリングするときに、矢印関数を実行します.
じっこうじょうけん
  • 初回レンダリング無条件実行
  • の2回目の実行から、2番目の配列[](依存配列)の要素をチェックし、要素が変化すると、関数
  • を実行します.
  • 「依存」(Dependency)配列が空の場合、この関数は再実行されません.
  •   // 두번째 인자의 []! 디펜던시 어레이라고 불러요. 여기 넣어준 값이 변하면 첫번째 인자인 콜백함수를 실행합니다.
      React.useEffect(() => {
        // 여기가 rendering 때 실행될 구문이 들어가는 부분입니다.
        // componentDidMount, componentDidUpdate일 때 동작하는 부분이 여기예요.
        // do something ...
    
        return () => {
            // 여기가 clean up 부분입니다.
            // componentWillUnmount 때 동작하는 부분이 여기예요.
          //do something ...
        };
      }, []);
    import React from "react";
    
    const Text = (props) => {
      const text = React.useRef(null); //<h1>태그 받아 옴
    
      const hoverEvent = () => {
        text.current.style.background = "yellow";
      } //배경색 노랑으로 할 꺼임
      React.useEffect(() => {
        text.current.addEventListener("mouseover", hoverEvent); //마우스 위로 올라왔을때 변경
    
        //unmount 될 때
        return () => {
          text.current.removeEventListener("mouseover", hoverEvent); 
        }
      }, [text]);
      
      return (
        <h1 ref={text}>텍스트입니다!</h1>
    )
    }
    
    export default Text;

    ルート


    Single Page Application(SPA)


    名前の通り、サーバにはhtmlのアプリケーションが1つしかありません.
    従来のWebサイトがページを移動するたびにhtml、css、js(=静的リソース)をサーバからダウンロードする場合、SPAは静的リソースを1回しか受け入れません.

  • どうしてhtmlをくれないの?
    多くの理由がありますが、最も重要なのは可用性です.
    ページを移動するたびにサーバが提供するhtmlに画面を切り替えると、変更されていない部分を再ロードしても状態を維持することが難しく、効率が低下します.
    (会員登録時にユーザーが記入した内容が失われる場合があります.
    ブログでは、各ページに新しいhtmlが受信された場合、変更されたのは文章だけですが、すべてのタイトルとカテゴリを再ロードする必要があります.)

  • 欠点はありませんか.
    →欠点もあります.SPAは静的リソースを一度だけ取得するため、最初はすべてのコンポーネントを受信します.
    つまり、すべてのユーザーが入りたくないページを持ってきます.しかも一度に全部持ってきて、たくさんの素子があれば、最初のロード速度が遅くなります.
  • SPAはどのように住所を移動しますか?
    htmlは1つしかありませんが、SPAはブラウザのアドレスウィンドウに従って他のページを表示することもできます.ブラウザのアドレスによって異なるページが表示されることをルーティングと呼びます.

    はんのうルート


    react-router-domのインストールyarn add react-router-dom

    適用方法


    1. index.BrowserRouterをjsに適用
    import React from 'react';
    import ReactDOM from "react-dom";
    import { BrowserRouter } from "react-router-dom";
    import './index.css';
    import App from './App';
    import reportWebVitals from './reportWebVitals';
    
    // 이부분이 index.html에 있는 div#root에 우리가 만든 컴포넌트를 실제로 랜더링하도록 연결해주는 부분입니다.
    ReactDOM.render(
      <BrowserRouter>
        <App />
      </BrowserRouter>,
      document.getElementById("root")
    );
    
    // If you want to start measuring performance in your app, pass a function
    // to log results (for example: reportWebVitals(console.log))
    // or send to an analytics endpoint. Learn more: https://bit.ly/CRA-vitals
    reportWebVitals();
    ブラウザ(BrowserRouter)は、Webブラウザが所有するアドレスに関する情報をpropsに渡す.
    2. App.jsにRouteを適用する<Link/>使用方法
    htmlにおけるリンクコンポーネントの役割はaラベルと似ている.反応領域内でページ切り替えを行います.<Link to="주소">[텍스트]</Link>
    import {Link, Route} from 'react-router-dom';
    import Cat from './Cat';
    import Dog from './Dog';
    import Home from './Home';
    
    function App() {
      return (
        <div className="App">
        //링크 적용방법
          <div>
            <Link to="/">Home 가기</Link>
            <Link to="/cat">Cat 가기</Link>
            <Link to="dog/">Dog 가기</Link>
          </div>
         //라우트 적용방법
          <Route path='/'>
            <Home />
          </Route>
          <Route path='/cat'>
            <Cat />
          </Route>
          <Route path='/dog'>
            <Dog />
          </Route>
        </div>
      );
    }
    
    export default App;
    3.精確な応用
    /cat、/dogにHome構成部品が同時に表示されないようにする("/")
    <Route path='/' exact>
      <Home />
    </Route>
    
    <Route path='/cat'>
      <Cat />
    </Route>
    
    <Route path='/dog'>
      <Dog />
    </Route>
    4.URLパラメータの使用
  • パラメータ与えられた方法
  • <Route path='/cat/:cat_name'>
      <Cat />
    </Route>
    アドレスが/cat/以降に動的に変更される(動的ルーティング)
    :cat nameがどの変数名で受信されるか
    ex)/cat/perl, cat/nabi
  • パラメータ使用1-useparamsフックの使用
    アドレスに/cat/perlを入力と
  • になります.
    // Cat.js
    import React from "react";
    import { useParams } from "react-router-dom";
    
    const Cat = (props) => {
        const cat_name = useParams();
        console.log(cat_name);
      return (
          <div>고양이 화면입니다!</div>
      );
    };
    
    export default Cat;
    コンソールには{cat_name: "perl"}が表示されます.
  • パラメータ使用方法2-component-props取得
    App.jsで渡します.component={Cat}使用
  • <Route path='/cat:cat_name' component={Cat}>
      <Cat />
    </Route>
    Cat.jsから取得
    import React from "react";
    
    const Cat = (props) => {
    	console.log(props);
    	return <div>고양이 화면입니다!</div>;
    };
    
    export default Cat;
    コンソール内のすべてのオブジェクト

    useHistoryの使用

    import React from "react";
    import { useHistory } from "react-router-dom";//useHistory가져옴
    
    const Home = (props) => {
      let history = useHistory(); //useHistory를 history로
      return (
        <>
          <div>메인 화면이에요.</div>
        
    	//버튼을 누르면 cat페이지 이동
          <button onClick={() => {history.push("/cat");}}> 
            cat으로 가기
          </button>
        </>
      );
    };
    
    export default Home;

    アドレス処理が無効です


    NotFound.jsファイルの作成
    import React from "react";
    
    const NotFound = (props) => {
      return <h1>주소가 올바르지 않아요!</h1>;
    };
    
    export default NotFound;
    App.jsから読み込みます.スイッチも呼び出されます.import NotFound from "./NotFound"; import { Route, Switch } from "react-router-dom";経路は<Switch>に囲まれている.switchに正しいパスがない場合、指定されていないパスの最後のページが表示されます.
    <Switch>
      <Route path='/' exact>
        <BucketList list={list} />
      </Route>
      <Route path='/detail/:index' >
        <Detail />
      </Route>
      <Route>
        <NotFound />
      </Route>
    </Switch>

    冗長管理による応答ステータス


    リアクターはstateのみを解放し、子供に親のstate値を修正させることはできません.また、親に子供がたくさんいる場合は、自分の状態を伝え続けなければなりません.したがって,地域間でデータを管理できる冗長性が必要である.
  • (1)Ridex Storeをコンポーネントに接続します.
  • (2)コンポーネントが状態変化を必要とする場合にActionを呼び出す.
  • (3)Reducerで新しい状態値を作成し、
  • (4)新しい状態値をStoreに格納します.
  • (5)コンポーネントは、新しいステータス値を受け入れる.△propsで受け取ったら、再登録されるでしょう.
  • ショップはデータ・リポジトリであり、コンポーネントはショップのデータ値を購読します.
    componentがデータ値を変更すると、リダイレクトにショップの値を変更するアクションが送信されます.(ディスパッチ動作)
    リカバリ・プログラムでデータ値を変更し、ショップに保存します.
    ショップは、変更した値を購読中のコンポーネントに渡します.
    これにより、画面に新しいデータが表示されます.

    道徳を知る


    レプリケーションパッケージのインストールyarn add redux react-redux
  • State
    ステータス値(データ)reduceに格納
    バイナリ形式{key:value}で保存します.
  • Action
    ステータスが変化する必要がある場合(=既存のデータを変更する場合)に発生します.
  • // 액션은 객체예요. 이런 식으로 쓰여요. type은 이름같은 거예요! 저희가 정하는 임의의 문자열을 넣습니다.
    {type: 'CHANGE_STATE', data: {...}}
  • ActionCreator
    アクション作成関数とも呼ばれます.アクションの作成に使用します.
  • //이름 그대로 함수예요!
    const changeState = (new_data) => {
    // 액션을 리턴합니다! (액션 생성 함수니까요. 제가 너무 당연한 이야기를 했나요? :))
    	return {
    		type: 'CHANGE_STATE',
    		data: new_data
    	}
    }
  • Reducer
    ワイヤに格納されている状態(=データ)を変更する関数です.
  • // 기본 상태값을 임의로 정해줬어요.
    const initialState = {
    	name: 'mean0'
    }
    
    function reducer(state = initialState, action) {
    	switch(action.type){
    
    		// action의 타입마다 케이스문을 걸어주면, 
    		// 액션에 따라서 새로운 값을 돌려줍니다!
    		case CHANGE_STATE: 
    			return {name: 'mean1'};
    
    		default: 
    			return false;
    	}	
    }

  • store
    グローバルデータストア

  • dispatch
    アクションを刺激するキャラクターdispatch(action);
  • 冗長性の使用


    アヒルの構造
    ワイヤ構造は、外観ではなく機能によって作成されます.

    redoxフォルダを作成すると、リポジトリconfigStoreが作成されます.jsファイル、modulesフォルダを作成します.
    モジュールの作成
    //modules폴더 안 bucket.js
    
    // Actions 액션 타입을 정해줍니다.
    const LOAD = "bucket/LOAD";
    const CREATE = "bucket/CREATE";
    
    // initialState 초기 상태값을 만들어줍니다.
    const initialState = {
      list: ["영화관 가기", "매일 책읽기", "수영 배우기"],
    };
    
    // Action Creators 액션 생성 함수를 작성합니다.
    // 액션 생성 함수예요.
    // 액션을 만들어줄 함수죠!
    export const loadBucket = (bucket) => {
      return { type: LOAD, bucket };
    };
    
    export const createBucket = (bucket) => {
      return { type: CREATE, bucket };
    };
    
    // Reducer 리듀서예요.
    // 실질적으로 store에 들어가 있는 데이터를 변경하는 곳이죠!
    export default function reducer(state = initialState, action = {}) {
      switch (action.type) {
        // do reducer stuff
        case "bucket/LOAD":
          return state;
    
        case "bucket/CREATE":
          const new_bucket_list = [...state.list, action.bucket];
          return { list: new_bucket_list };
    
        default:
          return state;
      }
    }
    
    ショップの作成
    //configStore.js
    import { createStore, combineReducers } from "redux";
    import bucket from "./modules/bucket";
    
    // root 리듀서를 만들어줍니다.
    // 나중에 리듀서를 여러개 만들게 되면 여기에 하나씩 추가해주는 거예요!
    const rootReducer = combineReducers({ bucket });
    
    // 스토어를 만듭니다.
    const store = createStore(rootReducer);
    
    export default store;

    ワイヤと構成部品の接続


    index.ショップをjsからコンポーネントに注入
    import React from 'react';
    import ReactDOM from 'react-dom';
    import './index.css';
    import App from './App';
    import reportWebVitals from './reportWebVitals';
    import {BrowserRouter} from "react-router-dom";
    
    // 우리의 버킷리스트에 리덕스를 주입해줄 프로바이더를 불러옵니다!
    import { Provider } from "react-redux";
    // 연결할 스토어도 가지고 와요.
    import store from "./redux/configStore";
    
    ReactDOM.render(
      <Provider store={store}>
        <BrowserRouter>
          <App />
        </BrowserRouter>
      </Provider>,
      document.getElementById("root")
    );

    構成部品でのワイヤデータの使用

  • リドスホーク
  • // useDispatch는 데이터를 업데이트할 때,
    // useSelector는 데이터를 가져올 때 씁니다.
    import {useDispatch, useSelector} from "react-redux";
  • ReduxデータのインポートuseSelector((state) ⇒ state.bucket)stateは完全なreduceデータ
  • を有する
    import { useSelector } from "react-redux";
    ...
     const my_lists = useSelector((state) => state.bucket.list);
  • Reduxデータ
  • を追加
    // useDispatch를 가져와요!
    import {useDispatch} from "react-redux";
    // 액션생성함수도 가져오고요!
    import { createBucket } from "./redux/modules/bucket";
    ...
    const dispatch = useDispatch();
    const addBucketList = () => {
        dispatch(createBucket(text.current.value));
      };