ReactJS 使用的调查网站
在这篇文章中,我们将使用ReactJS创建一个调查网站模板。这个项目基本上创建了一个单页网站,它将从用户处接收多个状态的输入并将其存储以供以后显示。用户需要输入基本信息,如姓名、电子邮件和联系电话。只有在填写完所有信息后,用户才能回答下一个问题。用户填写的信息将显示给用户以进行确认,用户必须确认并提交。整个网站的逻辑和后台操作都是使用JSX完成的。
网站的最终输出将看起来像这样:
使用的技术/先决条件:
- ReactJS
- Bootstrap
- CSS
- JSX
- 在ReactJS中导出默认函数
计划:
为了在React中创建一个多状态调查应用程序,我们首先创建所有所需的表单组件。我们创建一个名为“basicDetails”的组件,它将获取用户的基本详细信息并存储。接下来,我们创建一个问卷调查的组件,其中包含调查问题。第三个页面将显示用户输入的所有详细信息,并包含一个提交按钮,用于确认提交并将我们重定向到“ThankYou”页面。我们还将有其他组件,如“Header”,“Footer”和“About”部分。我们使用“useState”钩子创建一个后端,以获取表单中所有输入的值,并确保在最终的“EnteredDetails”页面之前它们被更改,通过实现“useEffect”钩子。为了存储临时数据,我们将使用localStorage存储用户数据。样式将使用Bootstrap进行设计。我们将使用React的“react-router-dom”包在网站中进行导航。
创建应用程序的步骤:
步骤1: 设置React项目:打开终端并运行以下命令以创建一个新的React项目(在“< >”中输入项目名称)
npx create-react-app <<name of project>>
步骤2: 更改目录:转到项目的目录。
cd <<name of project>>
步骤3: 安装路由器包:安装React路由器包,这将使我们能够在网站中进行导航。
npm install react-router-dom
步骤4: 从 Bootstrap 网站中导入 Bootstrap 的 css 和 js 的导入文件到 public 文件夹下的 index.html 文件中,这将使我们能够使用 Bootstrap 的样式和方法。
<link href=
"https://cdn.jsdelivr.net/npm/bootstrap@5.0.2/dist/css/bootstrap.min.css"
rel="stylesheet"
integrity=
"sha384-EVSTQN3/azprG1Anm3QDgpJLIm9Nao0Yz1ztcQTwFspd3yD65VohhpuuCOmLASjC"
crossorigin="anonymous">
<script src=
"https://cdn.jsdelivr.net/npm/bootstrap@5.0.2/dist/js/bootstrap.bundle.min.js"
integrity=
"sha384-MrcW6ZMFYlzcLA8Nl+NtUVF0sA7MsXsP1UyJoMp4YLEuNSfAP+JcXn/tWtIaxVXM"
crossorigin="anonymous">
</script>
步骤5: 在src目录中创建一个名为Components的文件夹,并创建About.js、AdditionalQuestions.js、BasicInfo.js、EnteredDetails.js、Footer.js、Header.js、ThankYouPage.js这些文件
项目结构:
在‘package.json’中的依赖项应该是这样的:
"dependencies": {
"@testing-library/jest-dom": "^5.16.5",
"@testing-library/react": "^13.4.0",
"@testing-library/user-event": "^13.5.0",
"react": "^18.2.0",
"react-dom": "^18.2.0",
"react-router-dom": "^6.14.1",
"react-scripts": "5.0.1",
"web-vitals": "^2.1.4"
}
示例: 在相应的文件中编写以下代码:
- App.js: 此文件导入所有组件并在网页上呈现。
- App.css: 此文件包含应用程序的样式。
// App.js
import './App.css';
import React, { useEffect, useState } from 'react';
import { BrowserRouter as Router, Routes, Route } from 'react-router-dom';
import BasicInfo from './Components/BasicInfo';
import AdditionalQuestions from './Components/AdditionalQuestions';
import EnteredDetails from './Components/EnteredDetails';
import ThankYouPage from './Components/ThankYouPage';
import { About } from './Components/About';
function App() {
// Initialize basicData state from localStorage or an empty object
const initBasicData = JSON.parse(localStorage.getItem('data')) || {};
// Initialize questionData state from localStorage or an empty object
const initQuestionsData = JSON.parse(localStorage.getItem('questiondata')) || {};
// Set up state hooks for basicData and questionData
const [basicData, setBasicData] = useState(initBasicData);
const [questionData, setQuestionData] = useState(initQuestionsData);
// Update localStorage whenever basicData changes
useEffect(() => {
localStorage.setItem('data', JSON.stringify(basicData));
}, [basicData]);
// Update localStorage whenever questionData changes
useEffect(() => {
localStorage.setItem('questiondata', JSON.stringify(questionData));
}, [questionData]);
// Function to add basicData to state and localStorage
const addBasicData = (name, email, contact) => {
// Create an object with the provided basic data
const myBasicData = {
name: name,
email: email,
contact: contact
};
// Update the basicData state with the new data
setBasicData(myBasicData);
// Update the localStorage with the new basicData
localStorage.setItem("data", JSON.stringify(myBasicData));
}
// Function to add questionData to state and localStorage
const addQuestionData = (profession, interest, reference) => {
// Create an object with the provided question data
const myQuestionData = {
profession: profession,
interest: interest,
reference: reference
};
// Update the questionData state with the new data
setQuestionData(myQuestionData);
// Update the localStorage with the new questionData
localStorage.setItem("questiondata", JSON.stringify(myQuestionData));
}
// Render the application
return (
<Router>
{/* Define the routes */}
<Routes>
{/* Render the BasicInfo component with the addBasicData function */}
<Route path='/' element={<BasicInfo addBasicData={addBasicData} />} />
{/* Render the AdditionalQuestions component with the addQuestionData function */}
<Route
path='/questions'
element={<AdditionalQuestions addQuestionData={addQuestionData} />}
/>
{/* Render the EnteredDetails component with basicData and questionData */}
<Route
path='/details'
element={<EnteredDetails data={basicData} questiondData={questionData} />}
/>
{/* Render the ThankYouPage component */}
<Route
path='/thanks'
element={<ThankYouPage />}
/>
{/* Render the About component */}
<Route
path='/about'
element={<About />}
/>
</Routes>
</Router>
);
}
// Export the App component as the default export
export default App;
CSS
/* App.css */
body{
background-color: #F2EAD3;
}
.navbar{
width : 59vw;
text-decoration: none;
height: 5vh;
top: 0%;
position: fixed;
}
.qform{
margin-top: 10vh;
margin-bottom: 5vh;
z-index: 0;
}
.badge{
color: black;
}
.footer {
background-color: green;
position: fixed;
width: 100%;
bottom: 0;
color: white;
}
将以下代码写入Components文件夹中创建的文件中:
- BasicInfo.js: 在此收集用户的基本信息。
- AdditionalQuestions.js: 在此收集用户提供的额外信息。
- EnteredDetails.js: 在此显示所有数据提交后重新输入的详细信息。
- Header.js: 此组件显示网页的页眉。
- Footer.js: 此组件显示网页的页脚。
- ThankYouPage.js: 在收集到所有信息后,该页面显示。
- About.js: 在此页面上显示有关网页的额外信息。
BasicInfo.js
// BasicInfo.js
import React, { useState } from 'react';
import { useNavigate } from 'react-router-dom';
export default function BasicInfo({ addBasicData }) {
// State variables to store user input
const [name, setName] = useState("");
const [email, setEmail] = useState("");
const [contact, setContact] = useState("");
// Navigation function for programmatic routing
const navigate = useNavigate();
// Function to handle form submission
const submit = (e) => {
e.preventDefault();
if (!name || !email || !contact) {
// Alert if any field is missing
alert("All fields necessary!");
} else {
// Call the addBasicData function provided by the parent component
addBasicData(name, email, contact);
// Navigate to the '/questions' route
navigate('/questions');
}
}
return (
<div className="container-fluid qform">
<div className="col-md-5 m-auto">
<div className="mt-3">
<div className="card text-left h-100">
<div className="card-body my-3">
<form onSubmit={submit}>
<label htmlFor="">
<h4>Basic Details</h4>
</label>
<div className="form-group my-3">
<label htmlFor="">
<b>1.</b> Name
</label>
{/* Input field for name */}
<input
type="text"
name="name"
value={name}
onChange={(e) => { setName(e.target.value) }}
className='form-control my-2'
placeholder='Enter your Name'
autoComplete='off'
/>
</div>
<div className="form-group my-3">
<label htmlFor="">
<b>2.</b> Email
</label>
{/* Input field for email */}
<input
type="email"
name='email'
value={email}
onChange={(e) => { setEmail(e.target.value) }}
className='form-control my-2'
placeholder='Enter your Email'
autoComplete='off'
/>
</div>
<div className="form-group my-3">
<label htmlFor="">
<b>3.</b> Contact No.
</label>
{/* Input field for contact number */}
<input
type="tel"
name='contact'
value={contact}
onChange={(e) => { setContact(e.target.value) }}
className='form-control my-2'
placeholder='Enter your Contact No.'
autoComplete='off'
/>
</div>
{/* Submit button */}
<button type='submit' className='btn btn-success mx-3'>Next</button>
</form>
{/* 步骤indicators */}
<center>
<span className="badge badge-pill bg-success"><b>1</b></span>
<span className="badge rounded-pill disabled">2</span>
<span className="badge rounded-pill disabled">3</span>
</center>
</div>
</div>
</div>
</div>
</div>
)
}
AdditionalQuestions.js
// AdditionalQuestions.js
import React, { useState } from 'react';
import { useNavigate } from 'react-router-dom';
export default function AdditionalQuestions({ addQuestionData }) {
// State variables to store user inputs
const [profession, setProfession] = useState("");
const [interest, setInterest] = useState("");
const [reference, setReference] = useState("");
const [otherProfession, setOtherProfession] = useState("");
const [otherInterest, setOtherInterest] = useState("");
const [otherReference, setOtherReference] = useState("");
const navigate = useNavigate();
// Function to handle form submission
const submit = (e) => {
e.preventDefault();
// Check if all fields are filled
if (!profession || !interest || !reference) {
alert("All fields necessary!");
} else {
// If the selected option is "Others", use the value from the corresponding text input
if (profession === "Others") {
profession = otherProfession;
}
if (interest === "Others") {
interest = otherInterest;
}
if (reference === "Others") {
reference = otherReference;
}
// Log the selected options and call the addQuestionData function with the data
console.log(profession, interest, reference);
addQuestionData(profession, interest, reference);
// Navigate to the next page
navigate('/details');
}
};
// Event handler for changes in the profession radio buttons
const handleProfessionChange = (e) => {
setProfession(e.target.value);
};
// Event handler for changes in the interest radio buttons
const handleInterestChange = (e) => {
setInterest(e.target.value);
};
// Event handler for changes in the reference radio buttons
const handleReferenceChange = (e) => {
setReference(e.target.value);
};
return (
<div className="container-fluid qform">
<div className="col-md-5 m-auto">
<div className="mt-3">
<div className="card text-left h-100">
<div className="card-body">
<form onSubmit={submit}>
<label htmlFor="">
<h4>Additional Questions</h4>
</label>
{/* Profession options */}
<div className="form-group m-2" onChange={handleProfessionChange}>
<label htmlFor="q1">
<b>1.</b> What is your profession?
</label>
<br />
<input
type="radio"
name="ProfessionRadio"
id="student"
autoComplete="off"
className="m-2"
value="Student"
/>
<label htmlFor="student"> Student</label>
<br />
{/* Other options for profession with text input */}
<input
type="radio"
name="ProfessionRadio"
id="sde"
autoComplete="off"
className="m-2"
value="Software Engineer"
/>
<label htmlFor="sde"> Software Engineer</label>
<br />
<input
type="radio"
name="ProfessionRadio"
id="teacher"
autoComplete="off"
className="m-2"
value="Teacher"
/>
<label htmlFor="teacher"> Teacher</label>
<br />
<input
type="radio"
name="ProfessionRadio"
id="others"
autoComplete="off"
className="m-2"
value="Others"
/>
<label htmlFor="others"> Others:</label>
<input
type="text"
id="otherProfession"
autoComplete="off"
className="form-control m-2"
value={otherProfession}
onChange={(e) => { setOtherProfession(e.target.value) }}
/>
<hr />
</div>
{/* Interest options */}
<div className="form-group m-2" onChange={handleInterestChange}>
<label htmlFor="q2">
<b>2.</b> What are your interests?
</label>
<br />
<input
type="radio"
name="interestRadio"
id="dsa"
autoComplete="off"
className="m-2"
value="DSA"
/>
<label htmlFor="dsa"> DSA</label>
<br />
{/* Other options for interest with text input */}
<input
type="radio"
name="interestRadio"
id="fullstack"
autoComplete="off"
className="m-2"
value="Full Stack Development"
/>
<label htmlFor="fullstack"> Full Stack Development</label>
<br />
<input
type="radio"
name="interestRadio"
id="dataScience"
autoComplete="off"
className="m-2"
value="Data Science"
/>
<label htmlFor="dataScience"> Data Science</label>
<br />
<input
type="radio"
name="interestRadio"
id="compeProgramming"
autoComplete="off"
className="m-2"
value="Competitive Programming"
/>
<label htmlFor="compeProgramming"> Competitive Programming</label>
<br />
<input
type="radio"
name="interestRadio"
id="others"
autoComplete="off"
className="m-2"
value="Others"
/>
<label htmlFor="others"> Others:</label>
<input
type="text"
id="otherInterest"
autoComplete="off"
className="form-control m-2"
value={otherInterest}
onChange={(e) => { setOtherInterest(e.target.value) }}
/>
<hr />
</div>
{/* Reference options */}
<div className="form-group m-2" onChange={handleReferenceChange}>
<label htmlFor="q3">
<b>3.</b> Where did you hear about us?
</label>
<br />
<input
type="radio"
name="referenceRadio"
id="news"
autoComplete="off"
className="m-2"
value="News Paper"
/>
<label htmlFor="news"> News Paper</label>
<br />
<input
type="radio"
name="referenceRadio"
id="LinkedIn"
autoComplete="off"
className="m-2"
value="LinkedIn"
/>
<label htmlFor="LinkedIn"> LinkedIn</label>
<br />
<input
type="radio"
name="referenceRadio"
id="Instagram"
autoComplete="off"
className="m-2"
value="Instagram"
/>
<label htmlFor="Instagram"> Instagram</label>
<br />
<input
type="radio"
name="referenceRadio"
id="others"
autoComplete="off"
className="m-2"
value="Others"
/>
<label htmlFor="others"> Others:</label>
<input
type="text"
id="otherReference"
autoComplete="off"
className="form-control m-2"
value={otherReference}
onChange={(e) => { setOtherReference(e.target.value) }}
/>
<br />
</div>
{/* Submit button */}
<button type="submit" className="btn btn-success mx-3">
Next
</button>
</form>
{/* Progress indicators */}
<center>
<span className="badge rounded-pill disabled">1</span>
<span className="badge badge-pill bg-success">
<b>2</b>
</span>
<span className="badge rounded-pill disabled">3</span>
</center>
</div>
</div>
</div>
</div>
</div>
);
}
EnteredDetails.js
// EnteredDetails.js
import { useNavigate } from 'react-router-dom';
export default function EnteredDetails(props) {
const navigate = useNavigate();
// Function to handle form submission
const submit = () => {
console.log(props.data); // Log basicData object
console.log(props.questiondData); // Log questionData object
navigate('/thanks'); // Navigate to the thanks page
};
return (
<div className="container-fluid qform">
<div className="col-md-5 m-auto">
<div className="mt-3">
<div className="card text-left h-100">
<div className="card-body my-3">
<h4>Entered Details</h4>
{/* Display basicData */}
<p>
<b>Name:</b> {props.data.name}
</p>
<p>
<b>Email:</b> {props.data.email}
</p>
<p>
<b>Contact No.:</b> {props.data.contact}
</p>
<h4>Responses</h4>
{/* Display questionData */}
<p>
<b>Profession:</b> {props.questiondData.profession}
</p>
<p>
<b>Interests:</b> {props.questiondData.interest}
</p>
<p>
<b>Reference:</b> {props.questiondData.reference}
</p>
{/* Submit button */}
<button type="submit" onClick={submit} className="btn btn-success">
Submit
</button>
{/* Page numbers */}
<center>
<span className="badge rounded-pill disabled">1</span>
<span className="badge rounded-pill disabled">2</span>
<span className="badge badge-pill bg-success">
<b>3</b>
</span>
</center>
</div>
</div>
</div>
</div>
</div>
);
}
ThankYouPage.js
// ThankYouPage.js
import React from 'react';
function ThankYouPage() {
return (
<div className="container-fluid qform">
<div className="col-md-5 m-auto">
<div className="mt-3">
<div className="card text-left h-100">
<div className="card-body my-3">
<h3>Thank You for your Response!</h3>
<h6>You may close this tab now.</h6>
</div>
</div>
</div>
</div>
</div>
);
}
export default ThankYouPage;
About.js
// About.js
import React from 'react'
export const About = () => {
return (
<div className='text-center qform'>
<h3>This is About Section</h3>
<p>This is a survey website example using ReactJS</p>
</div>
)
}
运行应用程序的步骤:
步骤1: 要运行网站,请在网站目录中打开一个终端并运行以下命令。
npm start
步骤2: 打开网络浏览器,在地址栏中输入以下URL(默认):
http://localhost:3000/
输出: