フリーランス 技術調査ブログ

フリーランス/エンジニア Ruby Python Nodejs Vuejs React Dockerなどの調査技術調査の備忘録

ReactHooksとreact-routerを利用して各画面でデータを持ちまわる

目的

udemyのReactHooksの入門編の受講を完了したので覚えている範囲で簡単なサンプルプログラムを作成する。 ※コースの中にはreact-routerの説明はありません。react-bootstrapも利用していないです。また自分が初見で利用しております。 ReactHooksとreact-routerを利用して画面遷移の中、入力したデータを各画面で持ち回り表示するサンプルを作成しました。 素人なので、力業感が否めないですが、useState,useEffectAPIを利用するのと、localStorageを利用して強引にデータを持ちまわることが

インストールしたパッケージ

 # yarn add react-router-dom
 # yarn add react-bootstrap bootstrap

サンプルコード

import React, { useState, useEffect } from 'react'
import { Nav, Container, Form } from 'react-bootstrap';

import {
  BrowserRouter as Router,
  Switch,
  Route,
  Link,
  useRouteMatch,
  useParams
} from 'react-router-dom'

import 'bootstrap/dist/css/bootstrap.min.css';



const App = (props) => {
  const appState = localStorage.getItem('appWithProps')
  const initialState = appState ? JSON.parse(appState) : props
  const [state, setState] = useState(initialState)

  useEffect(() => {
    localStorage.setItem('appWithProps', JSON.stringify(state))
  }, [state])

  const emailInputChange = (e) => setState({ ...state, email: e.target.value })

  return (
    <Router>
      <Container fluid>
        <Nav>
          <Nav.Item>
            <Nav.Link href="/">Home</Nav.Link>
          </Nav.Item>
          <Nav.Item>
            <Nav.Link href="/about">About</Nav.Link>
          </Nav.Item>
          <Nav.Item>
            <Nav.Link href="/topics">Topics</Nav.Link>
          </Nav.Item>
        </Nav>

        <Form>
          <Form.Group controlId="formBasicEmail">
            <Form.Label>Email address</Form.Label>
            <Form.Control type="email" placeholder="Enter email" value={state.email} onChange={emailInputChange} />
          </Form.Group>
        </Form>
        <Switch>
          <Route path="/about">
            <About email={state.email} />
          </Route>
          <Route path="/topics">
            <Topics email={state.email} />
          </Route>
          <Route path="/">
            <Home email={state.email} />
          </Route>
        </Switch>
      </Container>
    </Router>
  );
}

const Home = (props) => {
  return (
    <>
      <h2>Home</h2>
      <hr />
      <h4>MailAddress: {props.email}</h4>
    </>
  )
}

const About = (props) => {
  return (
    <>
      <h2>About</h2>
      <hr />
      <h4>MailAddress: {props.email}</h4>
    </>
  )
}

const Topics = (props) => {
  let match = useRouteMatch();

  return (
    <div>
      <h2>Topics</h2>
      <hr />
      <h4>MailAddress: {props.email}</h4>
      <ul>
        <li>
          <Link to={`${match.url}/components`}>Components</Link>
        </li>
        <li>
          <Link to={`${match.url}/props-v-state`}>
            Props v. State
          </Link>
        </li>
      </ul>

      <Switch>
        <Route path={`${match.path}/:topicId`}>
          <Topic />
        </Route>
        <Route path={match.path}>
          <h3>Please select a topic.</h3>
        </Route>
      </Switch>
    </div>
  );
}

const Topic = () => {
  let { topicId } = useParams();
  return <h3>Requested topic ID: {topicId}</h3>;
}

App.defaultProps = {
  name: '',
  email: ''
}

export default App;

画面イメージ

f:id:PX-WING:20200522011723p:plain