反応基础クラス-3
Event Listener
ユーザーの動作(=イベント)
イベントリスナーは
<div onClick={}>
のようにエリー小屋に直接入れることができますが、addEventListenerで追加できます.反応関数型では
useEffect()
反応フックを用いた.リアクションフックは、ライフサイクル関数のコンポーネントDidMountとコンポーネントDidUpdateとコンポーネントWillUnmountの組み合わせです.
React.useEffect(() => {}, []);
構成部品をレンダリングするときに、矢印関数を実行します.じっこうじょうけん
// 두번째 인자의 []! 디펜던시 어레이라고 불러요. 여기 넣어준 값이 변하면 첫번째 인자인 콜백함수를 실행합니다.
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は静的リソースを一度だけ取得するため、最初はすべてのコンポーネントを受信します.
つまり、すべてのユーザーが入りたくないページを持ってきます.しかも一度に全部持ってきて、たくさんの素子があれば、最初のロード速度が遅くなります.
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
アドレスに/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"}
が表示されます.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値を修正させることはできません.また、親に子供がたくさんいる場合は、自分の状態を伝え続けなければなりません.したがって,地域間でデータを管理できる冗長性が必要である.
componentがデータ値を変更すると、リダイレクトにショップの値を変更するアクションが送信されます.(ディスパッチ動作)
リカバリ・プログラムでデータ値を変更し、ショップに保存します.
ショップは、変更した値を購読中のコンポーネントに渡します.
これにより、画面に新しいデータが表示されます.
道徳を知る
レプリケーションパッケージのインストール
yarn add redux react-redux
ステータス値(データ)reduceに格納
バイナリ形式{key:value}で保存します.
ステータスが変化する必要がある場合(=既存のデータを変更する場合)に発生します.
// 액션은 객체예요. 이런 식으로 쓰여요. type은 이름같은 거예요! 저희가 정하는 임의의 문자열을 넣습니다.
{type: 'CHANGE_STATE', data: {...}}
アクション作成関数とも呼ばれます.アクションの作成に使用します.
//이름 그대로 함수예요!
const changeState = (new_data) => {
// 액션을 리턴합니다! (액션 생성 함수니까요. 제가 너무 당연한 이야기를 했나요? :))
return {
type: 'CHANGE_STATE',
data: new_data
}
}
ワイヤに格納されている状態(=データ)を変更する関数です.
// 기본 상태값을 임의로 정해줬어요.
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";
useSelector((state) ⇒ state.bucket)
stateは完全なreduceデータimport { useSelector } from "react-redux";
...
const my_lists = useSelector((state) => state.bucket.list);
// useDispatch를 가져와요!
import {useDispatch} from "react-redux";
// 액션생성함수도 가져오고요!
import { createBucket } from "./redux/modules/bucket";
...
const dispatch = useDispatch();
const addBucketList = () => {
dispatch(createBucket(text.current.value));
};
Reference
この問題について(反応基础クラス-3), 我々は、より多くの情報をここで見つけました https://velog.io/@lipton/리액트-기초반-3テキストは自由に共有またはコピーできます。ただし、このドキュメントのURLは参考URLとして残しておいてください。
Collection and Share based on the CC Protocol