はじめに
- 前回、テスト用のAPIを実行してReactで表示するサンプルプログラムを作成しました
- APIで取得したデータをローカルストレージで持ち待って、reactprouter-domでページ遷移したまま、APIで取得したデータを表示しつづけるプログラムを作成しました。
前回のテストAPIの記事
サンプルプログラム
Reactのバージョンは16.13.1となりますので、react-hooksが利用できるバージョンでお試しください。
import React, { useState, useEffect } from 'react' import { Nav, Container, Form, Button, Table } from 'react-bootstrap' import axios from 'axios' import Home from './Home' import UserInfo from './UserInfo' 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) const apiCall = async () => { const result = await axios( 'https://reqres.in/api/users?delay=1', ).then((response) => { setState({ ...state, data: response.data.data }); }) } useEffect( () => { const fetchData = async () => { const result = await axios( 'https://reqres.in/api/users?delay=1', ).then((response) => { setState({ ...state, data: response.data.data }); }) } fetchData() }, []) 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> <Table striped bordered hover> <thead> <tr> <th>#</th> <th>First Name</th> <th>Last Name</th> <th>email</th> <th>Avatar</th> </tr> </thead> <tbody> { state.data.map((d,index) => { return ( <UserInfo key={index} id={d.id} first_name={d.first_name} last_name={d.last_name} email={d.email} avatar={d.avatar} /> ); }) } </tbody> </Table> <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> <Button variant="primary" type="button" onClick={apiCall}>検索</Button> </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: '', data: [] } export default App;