我已经重新使用了用HTML / JS / CSS编写的旧代码,并试图让它做出反应,但是它不起作用。我可能做不到。
import React from 'react'
class ClassCreationForm extends React.Component {
render() {
// Questions Array
const questions = [
{ question: 'Enter Your First Name' },
{ question: 'Enter Your Last Name' },
{ question: 'Enter Your Email', pattern: /\S+@\S+\.\S+/ },
{ question: 'Create A Password', type: 'password' }
];
// Transition Times
const shakeTime = 100; // Shake Transition Time
const switchTime = 200; // Transition Between Questions
// Init Position At First Question
let position = 0;
// Init DOM Elements
const formBox = document.querySelector('#form-box');
const nextBtn = document.querySelector('#next-btn');
const prevBtn = document.querySelector('#prev-btn');
const inputGroup = document.querySelector('#input-group');
const inputField = document.querySelector('#input-field');
const inputLabel = document.querySelector('#input-label');
const inputProgress = document.querySelector('#input-progress');
const progress = document.querySelector('#progress-bar');
// EVENTS
// Get Question On DOM Load
document.addEventListener('DOMContentLoaded', getQuestion);
// Next Button Click
nextBtn.addEventListener('click', validate);
// Input Field Enter Click
inputField.addEventListener('keyup', e => {
if (e.keyCode == 13) {
validate();
}
});
// FUNCTIONS
// Get Question From Array & Add To Markup
function getQuestion() {
// Get Current Question
inputLabel.innerHTML = questions[position].question;
// Get Current Type
inputField.type = questions[position].type || 'text';
// Get Current Answer
inputField.value = questions[position].answer || '';
// Focus On Element
inputField.focus();
// Set Progress Bar Width - Variable to the questions length
progress.style.width = (position * 100) / questions.length + '%';
// Add User Icon OR Back Arrow Depending On Question
prevBtn.className = position ? 'fas fa-arrow-left' : 'fas fa-user';
showQuestion();
}
// Display Question To User
function showQuestion() {
inputGroup.style.opacity = 1;
inputProgress.style.transition = '';
inputProgress.style.width = '100%';
}
// Hide Question From User
function hideQuestion() {
inputGroup.style.opacity = 0;
inputLabel.style.marginLeft = 0;
inputProgress.style.width = 0;
inputProgress.style.transition = 'none';
inputGroup.style.border = null;
}
// Transform To Create Shake Motion
function transform(x, y) {
formBox.style.transform = `translate(${x}px, ${y}px)`;
}
// Validate Field
function validate() {
// Make Sure Pattern Matches If There Is One
if (!inputField.value.match(questions[position].pattern || /.+/)) {
inputFail();
} else {
inputPass();
}
}
// Field Input Fail
function inputFail() {
formBox.className = 'error';
// Repeat Shake Motion - Set i to number of shakes
for (let i = 0; i < 6; i++) {
setTimeout(transform, shakeTime * i, ((i % 2) * 2 - 1) * 20, 0);
setTimeout(transform, shakeTime * 6, 0, 0);
inputField.focus();
}
}
// Field Input Passed
function inputPass() {
formBox.className = '';
setTimeout(transform, shakeTime * 0, 0, 10);
setTimeout(transform, shakeTime * 1, 0, 0);
// Store Answer In Array
questions[position].answer = inputField.value;
// Increment Position
position++;
// If New Question, Hide Current and Get Next
if (questions[position]) {
hideQuestion();
getQuestion();
} else {
// Remove If No More Questions
hideQuestion();
formBox.className = 'close';
progress.style.width = '100%';
// Form Complete
formComplete();
}
}
// All Fields Complete - Show h1 end
function formComplete() {
const h1 = document.createElement('h1');
h1.classList.add('end');
h1.appendChild(
document.createTextNode(
`Thanks ${
questions[0].answer
} You are registered and will get an email shortly`
)
);
setTimeout(() => {
formBox.parentElement.appendChild(h1);
setTimeout(() => (h1.style.opacity = 1), 50);
}, 1000);
}
return(
<div id="container">
<h1 class="logo">Form Example</h1>
<div id="form-box">
<i id="prev-btn" class="fas fa-arrow-left"></i>
<i id="next-btn" class="fas fa-arrow-right"></i>
<div id="input-group">
<input id="input-field" required> </input>
<label id="input-label"></label>
<div id="input-progress"></div>
</div>
<div id="progress-bar"></div>
</div>
</div>
)
}
}
export default ClassCreationForm
我面临的问题是inputLabel.innerHTML
生成错误,因为inputLabel
为空。我认为这可能是我初始化谁不对的方式。
致谢
答案 0 :(得分:1)
我已经尝试向您展示React组件的基本结构。这至少应该运行并在标签元素中向您显示第一个问题。
我仍然建议您参加有关如何构建组件以及它们如何工作的教程。这是与常规(原始)JavaScript不同的样式,但是对于初学者来说,它具有很好的学习曲线。
别放弃,你会到达那里的!
import React from 'react'
class ClassCreationForm extends React.Component {
state: {
questions: [
{ phrase: 'Enter Your First Name' },
{ phrase: 'Enter Your Last Name' },
{ phrase: 'Enter Your Email', pattern: /\S+@\S+\.\S+/ },
{ phrase: 'Create A Password', type: 'password' }
],
shakeTime: 100,
switchTime: 200,
position: 0,
currentAnswer: ''
}
handleKeyUp(event) {
const { value, keyCode } = event;
this.setState({
currentAnswer: value
});
if (keyCode == 13) {
this.validate();
}
}
handleNextClick(event) {
this.validate();
}
validate() {
console.log(this.state.currentAnswer);
}
render() {
const { questions, position } = this.state;
const { phrase, type, pattern } = questions[position];
return (
<div id="container">
<h1 className="logo">Form Example</h1>
<div id="form-box">
<i id="prev-btn" className="fas fa-arrow-left"></i>
<i
id="next-btn"
className="fas fa-arrow-right"
onClick={this.handleNextClick}
></i>
<div id="input-group">
<input
id="input-field"
type={type || 'text'}
onKeyUp={this.handleKeyUp}
required
/>
<label id="input-label">
{ phrase }
</label>
<div id="input-progress"></div>
</div>
<div id="progress-bar"></div>
</div>
</div>
)
}
}