Main Course主な特長3講-React


特技3強!

  • react-routerは、アドレスに応じて異なるページを表示できます.
  • が事前に決められた住所でない場合、「あ!「人を間違えたんだ!」ページを見せてあげることができます.
  • Reduxを使用してステータス管理を行い、次のステータス管理プロセスを理解します.
    (デフォルト値がある→何をするか(「何をするかを決める!→何をするかを決める!」)プロセスは事前に必要です!)→値段が変わったんじゃないですか?→デバイスを教えて!
  • Redux hookを使用します.
  • Route

    yarn add react-router-dom

    index.BrowserRouterをjsに適用

    ...
    import { BrowserRouter } from "react-router-dom";
    
    ReactDOM.render(
      <BrowserRouter>
        <App />
      </BrowserRouter>,
      document.getElementById("root")
    );
    
    ...
  • 経路使用方法1:支柱なし交付時
  • <Route path="주소[/home 처럼 /와 주소를 적어요]" component={[보여줄 컴포넌트]}/>
  • Route使用方法2:支柱がある場合
  • <Route path="주소[/home 처럼 /와 주소를 적어요]" render={(props) => (<BucketList list={this.state.list} />)} />

    App.Routeをjsに適用

    ...
    import { Route } from "react-router-dom";
    
    ...  
      render(){
        return (
          <div className="App">
            <Route exact path="/" component={Home} />
            {/* '/' 이 기호가 /cat에도 있고 home path도 / 라서 메인으로 들어가면 컴포넌트가 중복 호출됨 -> exact 추가 */}
            <Route path="/cat" component={Cat} />
            <Route path="/dog" component={Dog} />
          </div>
        );
      }
    ...

    URLパラメータの使用

    //App.js
    ...
    // 파라미터 주기
    <Route path="/cat/:cat_name" component={Cat}/>
    
    ...
    //Cat.js
    ...
    const Cat = (props) => {
      console.log(props.match.params.cat_name);
      return (
        <div>고양이 화면이에요.</div>
      )
    }
    ...

    リンクの移動

  • リンク素子
  • を用いる.
    // App.js
    ...
    import { Link } from "react-router-dom";
    ...
    
    <div>
      <Link to="/">Home으로 가기</Link>
      <Link to="/cat">Cat으로 가기</Link>
      <Link to="/dog">Dog으로 가기</Link>
    </div>
  • 履歴オブジェクト使用関数の使用
    historyオブジェクトを使用するには、{withRouter}
  • を読み込む必要があります.
    // App.js
    ...
    import { withRouter } from "react-router";
    ...
    <button onClick={() => {
      // props에 있는 history를 사용합니다.
      // push([이동할 주소])는 페이지를 이동시켜 줍니다.
      this.props.history.push('/cat');
    }}>
    /cat으로 가기
    </button>
    <button onClick={()=>{
      // goBack()은 뒤로가기 예요.
      this.props.history.goBack();
    }}>뒤로가기
    </button>
    ...
    export default withRouter(App); // 내보내는 부분에서 withRouter로 감싸줍니다
  • Route実習の提出-遺願リストのDetailに移動
  • 無効なアドレスの処理

    // App.js
    ...
    import { Route, Switch } from "react-router-dom";
      ...
      render() {
        return (
          <div className="App">
            ...
              <Switch> // Switch가 모든 Route를 감싸야 정상 동작함.
                <Route
                  path="/"
                  exact
                  render={(props) => (
                    <BucketList
                      list={this.state.list}
                      history={this.props.history}
                    />
                  )}
                />
                <Route path="/detail" component={Detail} />
                <Route component={NotFound} /> // path를 안적음으로써 없는 path에 갔을때 NotFound 컴포넌트가 불러와짐.
              </Switch>
            ...
          </div>
        );
      }
    ...

    Redux

    yarn add redux react-redux

  • 冗長コンポーネント
    State, Action, ActionCreator, Reducer, Store, dispatch

  • Reduxの3つの特徴

  • storeは1つしか使いません.

  • storeのstate(データ)はactionにしか変更できません!

  • どんな要求があっても、隊長は同じ動作をしなければなりません.
    Reduserは純粋な関数でなければなりません.
    純粋な関数です
  • パラメータ以外の値に依存せず、
  • 以前の状態を変更します(=触れません).(変更する新しいオブジェクトを返さなければなりません.)
  • パラメータが同じ場合、
  • は常に同じ値を返します.
  • リーダは、以前の状態と動作をパラメータとする.
  • Reduxモジュールの作成

    // /src/redux/modules/bucket.js
    
    // Actions
    const LOAD = "bucket/LOAD";
    const CREATE = "bucket/CREATE";
    const DELETE = "bucket/DELETE";
    
    const initialState = {
      list: ["영화관 가기", "매일 책읽기", "수영 배우기"],
    };
    
    // Action Creators
    export const loadBucket = (bucket) => {
      return { type: LOAD, bucket };
    };
    
    export const createBucket = (bucket) => {
      return { type: CREATE, bucket };
    };
    
    export const deleteBucket = (bucket) => {
      return { type: DELETE, bucket };
    };
    
    // Reducer
    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};
    
        case "bucket/DELETE":
          const bucket_list = state.list.filter((l, idx) => {
            return idx !== action.bucket
          });
          return {list: bucket_list};
    
        default:
          return state;
      }
    }
    // /redux/configStore.js
    import { createStore, combineReducers } from "redux";
    import bucket from './modules/bucket';
    import { createBrowserHistory } from "history";
    
    // 브라우저 히스토리를 만들어줍니다.
    export const history = createBrowserHistory();
    // root 리듀서를 만들어줍니다.
    // 나중에 리듀서를 여러개 만들게 되면 여기에 하나씩 추가해주는 거예요!
    const rootReducer = combineReducers({ bucket });
    
    // 스토어를 만듭니다.
    const store = createStore(rootReducer);
    
    export default store;

    ストレージをアプリケーションに接続

    // index.js
    ...
    // 우리의 버킷리스트에 리덕스를 주입해줄 프로바이더를 불러옵니다!
    import { Provider } from "react-redux";
    // 연결할 스토어도 가지고 와요.
    import store from "./redux/configStore";
    ReactDOM.render(
      <Provider store={store}>
        <BrowserRouter>
          <App />
        </BrowserRouter>
      </Provider>,
      document.getElementById("root")
    );

    クラス構成部品でのReduxの使用


    1)冗長モジュールとconnect関数を読み込みます.
    2)アクションを作成するための関数を作成し、ステータス値と関数を取得します.
    3)connectを使用して構成部品とショップを整理します.
    4)コンソールのthis.道具を撮って△お店の値段がいいかどうか見てみましょう.
    5) this.stateのリストをクリアし、ショップの値に置き換えます!
    6)setStateをthisに設定します.props.createに変えましょう!
    // App.js
    ...
    // 리덕스 스토어와 연결하기 위해 connect라는 친구를 호출할게요!
    import {connect} from 'react-redux';
    // 리덕스 모듈에서 (bucket 모듈에서) 액션 생성 함수 두개를 가져올게요!
    import {loadBucket, createBucket} from './redux/modules/bucket';
    
    // 이 함수는 스토어가 가진 상태값을 props로 받아오기 위한 함수예요.
    const mapStateToProps = (state) => ({
      bucket_list: state.bucket.list,
    });
    
    // 이 함수는 값을 변화시키기 위한 액션 생성 함수를 props로 받아오기 위한 함수예요.
    const mapDispatchToProps = (dispatch) => ({
      load: () => {
        dispatch(loadBucket());
      },
      create: (new_item) => {
        dispatch(createBucket(new_item));
      }
    });
    
    ...
    
      addBucketList = () => {
        const new_item = this.text.current.value;
        this.props.create(new_item); // Redux의 create type을 적용해준 모습!
      };
    
      render() {
        return (
          ...
              <Switch>
                <Route
                  path="/"
                  exact
                  render={(props) => (
                    <BucketList
                      list={props.bucket_list} // store의 bucket_list를 props로 보내줌. (자식 컴포넌트에서도 store로 불러주면 되긴하지만, 아직 해당 작업을 안해줌.)
                      history={this.props.history}
                    />
                  )}
                />
    			...
              </Switch>
            ...
          </div>
        );
      }
    }
    ...
    // withRouter 적용
    // connect로 묶어줬습니다!
    export default connect(mapStateToProps, mapDispatchToProps)(withRouter(App));

    関数構成部品でのReduxの使用


    Reduxには関数素子用のHookもあります
    useSelector(), useDispatch()
    // BucketList.js
    ...
    // redux hook을 불러옵니다.
    import {useDispatch, useSelector} from 'react-redux';
    
    const BucketList = (props) => {
      // 버킷리스트를 리덕스 훅(useSelector)으로 가져오기
      const bucket_list = useSelector(state => state.bucket.list);
      
      return (
        <ListStyle>
          {bucket_list.map((list, index) => {
            return (
              <ItemStyle
                className="list_item"
                key={index}
                onClick={() => {
                  props.history.push("/detail");
                }}
              >
                {list}
              </ItemStyle>
            );
          })}
        </ListStyle>
      );
    };
    ...
    // Detail.js
    ...
    // redux hook을 불러옵니다.
    import { useDispatch, useSelector } from "react-redux";
    // 내가 만든 액션 생성 함수를 불러옵니다.
    import {deleteBucket} from "./redux/modules/bucket";
    
    const Detail = (props) => {
      const dispatch = useDispatch();
      
      // 스토어에서 상태값 가져오기
      const bucket_list = useSelector((state) => state.bucket.list);
      // url 파라미터에서 인덱스 가져오기
      let bucket_index = parseInt(props.match.params.index);
    
      return (
        <div>
          <h1>{bucket_list[bucket_index]}</h1>
          <button onClick={() => {
            dispatch(deleteBucket(bucket_index)); // delete type Action
          }}>삭제하기</button>
        </div>
      );
    };
    ...
    // App.js
    <Route
      path="/"
      exact
      render={(props) => (
        <BucketList
          // list={props.bucket_list} // 자식 컴포넌트에서도 store로 불러주면 되기때문에 더 이상 props로 bucket_list를 보내주지 않아도 됨.
          history={this.props.history}
          />
      )}
    />

    第3回テーマ




  • 課題の提出

  • URLパラメータを使用してstoreの配列の値をコミットする

  • Detailページに格納されている配列の要素値から要素を削除するコミット

  • 参考資料