【react-tabs】簡単にタブ実装を行うReactプラグイン
React
react-tabsとは?
簡単にタブ実装を行うためのnpmパッケージです。
リポジトリはこちらです
react-tabsでタブ実装してみた
実装してみました。
実装内容としてはマイページによくある「プロフィール情報」、「メールアドレス」、「パスワード」、「アイコン画像」の4タブからなるアカウント情報更新画面のようなものです。タブを切り替えても値が保持されるようにしました。
実装した感想としては本当に使いやすく、必要な時はすぐに導入したいなと感じました。
src/App.js
import "./App.css";
import EmailContextProvider from "./EmailContextProvider";
import IconContextProvider from "./IconContextProvider";
import PasswordContextProvider from "./PasswordContextProvider";
import ProfileContextProvider from "./ProfileContextProvider";
import SampleTab from "./SampleTab";
function App() {
return (
<div className="App">
<ProfileContextProvider>
<EmailContextProvider>
<PasswordContextProvider>
<IconContextProvider>
<SampleTab />
</IconContextProvider>
</PasswordContextProvider>
</EmailContextProvider>
</ProfileContextProvider>
</div>
);
}
export default App;
src/ProfileContextProvider.js
import React, { createContext, useState } from "react";
export const ProfileContext = createContext();
function ProfileContextProvider({ children }) {
const [userName, setUserName] = useState("");
const [nickName, setNickName] = useState("");
const [message, setMessage] = useState("");
const [notifyEmail, setNotifyEmail] = useState(false);
return (
<ProfileContext.Provider
value={{
userName,
setUserName,
nickName,
setNickName,
message,
setMessage,
notifyEmail,
setNotifyEmail,
}}
>
{children}
</ProfileContext.Provider>
);
}
export default ProfileContextProvider;
src/EmailContextProvider.js
import React, { createContext, useState } from "react";
export const EmailContext = createContext();
function EmailContextProvider({ children }) {
const [email, setEmail] = useState("");
return (
<EmailContext.Provider
value={{
email,
setEmail,
}}
>
{children}
</EmailContext.Provider>
);
}
export default EmailContextProvider;
src/PasswordContextProvider.js
import React, { createContext, useState } from "react";
export const PasswordContext = createContext();
function PasswordContextProvider({ children }) {
const [password, setPassword] = useState("");
return (
<PasswordContext.Provider
value={{
password,
setPassword,
}}
>
{children}
</PasswordContext.Provider>
);
}
export default PasswordContextProvider;
src/IconContextProvider.js
import React, { createContext, useState } from "react";
export const IconContext = createContext();
function IconContextProvider({ children }) {
const [icon, setIcon] = useState(null);
const [iconImage, setIconImage] = useState("");
const onChangeIcon = (e) => {
const files = e.target.files;
if (files && files[0]) {
setIcon(files[0]);
setIconImage(window.URL.createObjectURL(files[0]));
}
};
return (
<IconContext.Provider
value={{
onChangeIcon,
iconImage,
}}
>
{children}
</IconContext.Provider>
);
}
export default IconContextProvider;
src/SampleTabs.js
import React, { useState } from "react";
import { Tab, Tabs, TabList, TabPanel } from "react-tabs";
import "react-tabs/style/react-tabs.css";
import ProfileForm from "./ProfileForm";
import EmailForm from "./EmailForm";
import PasswordForm from "./PasswordForm";
import { IconContext } from "./IconContextProvider";
import IconForm from "./IconForm";
function SampleTab() {
return (
<Tabs defaultIndex={0}>
<TabList>
<Tab>プロフィール情報</Tab>
<Tab>メールアドレス</Tab>
<Tab>パスワード</Tab>
<Tab>アイコン画像</Tab>
</TabList>
<TabPanel>
<ProfileForm />
</TabPanel>
<TabPanel>
<EmailForm />
</TabPanel>
<TabPanel>
<PasswordForm />
</TabPanel>
<TabPanel>
<IconForm />
</TabPanel>
</Tabs>
);
}
export default SampleTab;
src/ProfileForm.js
import React, { useContext } from "react";
import { ProfileContext } from "./ProfileContextProvider";
function ProfileForm() {
const handleSubmit = (e) => {
e.preventDefault();
// do somthing... such as api call etc
};
const {
userName,
setUserName,
nickName,
setNickName,
message,
setMessage,
notifyEmail,
setNotifyEmail,
} = useContext(ProfileContext);
return (
<fonm
style={{
display: "flex",
"flex-direction": "column",
padding: "0 50px 0 50px",
}}
onSubmit={(e) => handleSubmit(e)}
>
<div>
<label htmlFor="userName">ユーザー名</label>
<input
id="userName"
type="text"
value={userName}
onChange={(e) => setUserName(e.target.value)}
/>
</div>
<div>
<label htmlFor="nickName">ニックネーム</label>
<input
id="nickName"
type="text"
value={nickName}
onChange={(e) => setNickName(e.target.value)}
/>
</div>
<div>
<label htmlFor="message">メッセージ</label>
<input
id="message"
type="textarea"
value={message}
onChange={(e) => setMessage(e.target.value)}
/>
</div>
<div>
<label htmlFor="notifyEmail">お知らせメールを受け取るか</label>
<input
id="notifyEmail"
type="checkbox"
checked={notifyEmail}
onChange={() => setNotifyEmail(!notifyEmail)}
/>
</div>
<input
type="submit"
style={{ margin: "10px 300px 0 300px" }}
value="更新する"
/>
</fonm>
);
}
export default ProfileForm;
src/EmailForm.js
import React, { useContext } from "react";
import { EmailContext } from "./EmailContextProvider";
function EmailForm() {
const handleSubmit = (e) => {
e.preventDefault();
// do somthing... such as api call etc
};
const { email, setEmail } = useContext(EmailContext);
return (
<fonm
style={{
display: "flex",
"flex-direction": "column",
padding: "0 50px 0 50px",
}}
onSubmit={(e) => handleSubmit(e)}
>
<div>
<label htmlFor="email">Eメール</label>
<input
id="email"
type="text"
value={email}
onChange={(e) => setEmail(e.target.value)}
/>
</div>
<input
type="submit"
style={{ margin: "10px 300px 0 300px" }}
value="更新する"
/>
</fonm>
);
}
export default EmailForm;
src/PasswordForm.js
import React, { useContext } from "react";
import { PasswordContext } from "./PasswordContextProvider";
function PasswordForm() {
const handleSubmit = (e) => {
e.preventDefault();
// do somthing... such as api call etc
};
const { password, setPassword } = useContext(PasswordContext);
return (
<fonm
style={{
display: "flex",
"flex-direction": "column",
padding: "0 50px 0 50px",
}}
onSubmit={(e) => handleSubmit(e)}
>
<div>
<label htmlFor="password">パスワード</label>
<input
id="password"
type="password"
value={password}
onChange={(e) => setPassword(e.target.value)}
/>
</div>
<input
type="submit"
style={{ margin: "10px 300px 0 300px" }}
value="更新する"
/>
</fonm>
);
}
export default PasswordForm;
src/IconForm.js
import React, { useContext } from "react";
import { IconContext } from "./IconContextProvider";
function IconForm() {
const handleSubmit = (e) => {
e.preventDefault();
// do somthing... such as api call etc
};
const { onChangeIcon, iconImage } = useContext(IconContext);
return (
<fonm
style={{
display: "flex",
"flex-direction": "column",
padding: "0 50px 0 50px",
}}
onSubmit={(e) => handleSubmit(e)}
>
<div>
<label htmlFor="icon">アイコン画像</label>
<input id="icon" type="file" onChange={(e) => onChangeIcon(e)} />
<div>
<img src={iconImage} width="400px" height="400px" />
</div>
</div>
<input
type="submit"
style={{ margin: "10px 300px 0 300px" }}
value="更新する"
/>
</fonm>
);
}
export default IconForm;