昨日のdebug修正を行い、登録したユーザー(developers)のプロフィールが表示されるようになりました。また、他ファイルにも間違いがあり、debugしました。
debugしていて気づいた一番大きな間違いは、ナビゲーションバーのファイル(Navbar.js)上で、テスト用に書いたコードをそのまま残してしまっていた(本来なら消さなければならない)ことです。昨日は何度かコードを見直したのですが、気づきませんでした。今日はすぐ気が付きましたので、やはり「疲れていない状態で見直す」ことがすごく大事なのかもしれません。
というわけで、プロフィールを表示させるためのコード(正しいもの)です。
①新フォルダに新ファイル作成してプロフィールが表示されるようにする client/src/components/profiles/Profiles.js
componentsの中に新しいフォルダ「profiles」を作成して、新しいファイル、Profiles.jsを作成しました。
React HooksのuseEffectを使用して、ユーザーのプロフィールを表示できるようにコードを書きました。ローディング中はスピナーを表示、ローディングが終わったらDevelopersと表示されるようになっています。
useEffectの部分は、最後の[]部分は最初空欄だったのですが、それではエラー表示が出てしまうということで、[getProfiles]と修正しました。
import React, { Fragment, useEffect } from "react"; import PropTypes from "prop-types"; import { connect } from "react-redux"; import Spinner from "../layout/Spinner"; import ProfileItem from "./ProfileItem"; import { getProfiles } from "../../actions/profile"; const Profiles = ({ getProfiles, profile: { profiles, loading } }) => { useEffect(() => { getProfiles(); }, [getProfiles]); return ( <Fragment> {loading ? ( <Spinner /> ) : ( <Fragment> <h1 className='large text-primary'>Developers</h1> <p className='lead'> <i className='fab fa-connectdevelop' /> Browse and connect with developers </p> <div className='profiles'> {profiles.length > 0 ? ( profiles.map(profile => ( <ProfileItem key={profile._id} profile={profile} /> )) ) : ( <h4>No profiles found...</h4> )} </div> </Fragment> )} </Fragment> ); }; Profiles.propTypes = { getProfiles: PropTypes.func.isRequired, profile: PropTypes.object.isRequired }; const mapStateToProps = state => ({ profile: state.profile }); export default connect( mapStateToProps, { getProfiles } )(Profiles);
②新しいファイルを作成して、プロフィールの詳細が表示されるようにするclient/src/components/profiles/ProfileItem.js
先程作成した「profiles」フォルダ内にProfileItem.jsというファイルを作成しました。そこで、プロフィール詳細である、ユーザーのID・名前・アバター、ステイタス(現在の状態)、会社、場所、スキルが表示されるようコーディングしました。
スキルは4つをMAXとするために、sliceとmapを使用しています。
import React from "react"; import { Link } from "react-router-dom"; import PropTypes from "prop-types"; const ProfileItem = ({ profile: { user: { _id, name, avatar }, status, company, location, skills } }) => { return ( <div className='profile bg-light'> <img src={avatar} alt='' className='round-img' /> <div> <h2>{name}</h2> <p> {status} {company && <span> at {company}</span>} </p> <p className='my-1'>{location && <span>{location}</span>}</p> <Link to={`/profile/${_id}`} className='btn btn-primary'> View Profile </Link> </div> <ul> {skills.slice(0, 4).map((skill, index) => ( <li key={index} className='text-primary'> <i className='fas fa-check' /> {skill} </li> ))} </ul> </div> ); }; ProfileItem.propTypes = { profile: PropTypes.object.isRequired }; export default ProfileItem;
③App.jsに新しいファイル情報を書き加える
まず、import部分にprofilesフォルダのProfiles.jsの情報を書き加えました。
import Profiles from "./components/profiles/Profiles";
const AppのSwitch内に新しいRouteを書き加えます。(profilesの一行のみ)
const App = () => { useEffect(() => { store.dispatch(loadUser()); }, []); return ( <Provider store={store}> <Router> <Fragment> <Navbar /> <Route exact path='/' component={Landing} /> <section className='container'> <Alert /> <Switch> <Route exact path='/register' component={Register} /> <Route exact path='/login' component={Login} /> <Route exact path='/profiles' component={Profiles} /> <PrivateRoute exact path='/dashboard' component={Dashboard} /> <PrivateRoute exact path='/create-profile' component={CreateProfile} /> <PrivateRoute exact path='/edit-profile' component={EditProfile} /> <PrivateRoute exact path='/add-experience' component={AddExperience} /> <PrivateRoute exact path='/add-education' component={AddEducation} /> </Switch> </section> </Fragment> </Router> </Provider> ); };
④ナビゲーションバーにprofilesページへのリンクを書き加え、developersのプロフィール情報を表示できるようコードを書き加える(debugした部分)client/src/components/layout/Navbar.js
本日debugしていて気づいたのが、このファイルにテスト用に書いていたコードを消していなかったということです。
プロフィールのページへのリンクだけで良かったところ、/#!というテスト用ページへのリンクを消していなかったので、昨日おかしなことになっていました。正しいコードを書くことができて本日はスッキリです。
import React, { Fragment } from "react"; import { Link } from "react-router-dom"; import { connect } from "react-redux"; import PropTypes from "prop-types"; import { logout } from "../../actions/auth"; const Navbar = ({ auth: { isAuthenticated, loading }, logout }) => { const authLinks = ( <ul> <li> <Link to='/profiles'>Developers</Link> </li> <li> <Link to='/dashboard'> <i className='fas fa-user' /> {""} <span ClassName='hide-sm'>Dashboard</span> </Link> </li> <li> <a onClick={logout} href='#!'> <i className='fas fa-sign-out-alt' /> {""} <span ClassName='hide-sm'>Logout</span> </a> </li> </ul> ); const guestLinks = ( <ul> <li> <Link to='/profiles'>Developers</Link> </li> <li> <Link to='/register'>Register</Link> </li> <li> <Link to='/login'>Login</Link> </li> </ul> ); return ( <nav className='navbar bg-dark'> <h1> <Link to='/'> <i className='fas fa-code' /> DevConnector </Link> </h1> {!loading && ( <Fragment>{isAuthenticated ? authLinks : guestLinks}</Fragment> )} </nav> ); }; Navbar.propTypes = { logout: PropTypes.func.isRequired, auth: PropTypes.object.isRequired }; const mapStateToProps = state => ({ auth: state.auth }); export default connect( mapStateToProps, { logout } )(Navbar);
これで、プロフィールのページに、登録したユーザー(developers=開発者)が並んで表示されるようになりました。今日になって新しい目でチェックしてみると意外とシンプルなミスでした。debugする時は疲れていない状態で何がおかしいのか考えると良いなと思いました。
⑤その他に気づいたミスをdebugした。import { Link } from "react-router-dom"を使用している時のリンクの飛ばし方を間違えている部分があったので修正
これはまた別ファイルの全く別件のミスなのですが、import { Link } from "react-router-dom";を使用している時は、<Link to="/リンク先ファイル名”></Link>としなければならないところ、aタグ(a href)で囲んだ時と同じようにリンク先を”http~.html"と書いてしまっていた箇所を発見しましたので、修正しました。
具体的には、AddExperience.jsというファイルのこの部分です。Go Backをクリックでダッシュボードに飛ぶようになっています。
<Link className='btn btn-light my-1' to='/dashboard'> Go Back </Link>
現在使用している教材と学習時間:本日の学習時間2.5時間(復習とdebugのみ)
Udemy:MERN Stack Front To Back: Full Stack React, Redux & Node.js by Brad Traversy
★Section10:Profile Display
-Lec 53 Finish Profile Actions & Reducer(前のブログ記事の内容)
-Lec54 Display Profiles (開発者=developersのプロフィールを表示するページの作成。昨日間違えた部分をdebugして修正。)
-Lec 55 Addressing The Console Warnings (ここまでの講座でエラーが出ている箇所を修正。React Hooksの修正含む。)
進捗状況:76%
学習時間2.5時間
★参考にした本★
「React.js & Next.js超入門」掌田津耶乃 (秀和システム)
Section4-1: Reduxを使ってみよう