我正在使用Mad Libs游戏,向用户提出如下问题:
输入名词
用户填写正确的名称,点击提交,然后现在隐藏文本输入,并显示下一个问题。
我知道它处理条件渲染以使其工作,但我不确定如何以及从何处开始。我写了一个用户故事,试着在写出来的时候继续跟进,但仍然有点迷失。我的用户故事是
当用户输入文本并点击提交(或输入键)时,文本输入将被隐藏(但不会被删除或删除,因为输入的值用于传递道具),并显示带有新输入的下一个文本输入直到。当所有问题都得到解答时,会调用Madlibs组件。
除了上面的用户故事之外,所有内容都已构建完成并正常工作。我此时没有收到错误,我根本不知道如何为此编写条件函数。
这是我的代码:
import React, { Component } from 'react';
import styled from 'styled-components';
import Crawler from './crawler';
const NextQuestion = styled.div`
position: absolute;
color: white;
display: block;
margin-top: 108px;
`;
class NameForm extends React.Component {
constructor(props) {
super(props);
this.state = {
value1: 'enter proper name',
value2: 'noun',
value3: 'enter another proper name',
newValue: '',
submitted: false,
input1: 0,
input2: 0,
input3: 0,
input4: 0,
input5: 0,
input6: 0,
input7: 0
};
this.handleFirstChange = event => this.handleChange(event, 'value1');
this.handleSecondChange = event => this.handleChange(event, 'value2');
this.handleThirdChange = event => this.handleChange(event, 'value3');
this.handleFourthChange = event => this.handleChange(event, 'value4');
this.handleFifthChange = event => this.handleChange(event, 'value5');
this.handleSixthChange = event => this.handleChange(event, 'value6');
this.handleSeventhChange = event => this.handleChange(event, 'value7');
this.handleSubmit = event => this._handleSubmit(event);
}
handleChange(event, type) {
let newState = {};
newState[type] = event.target.value;
this.setState(newState);
}
_handleSubmit(event) {
event.preventDefault();
let toggle = this.state.visable;
this.setState({ visable: !toggle });
}
render() {
const divStyle = {
marginTop: '50px',
color: 'white',
top: '25px',
position: 'absolute'
};
let question = null;
const show = this.state.visable;
if (show) {
question = (
<div>
<Crawler
properName1={this.state.value1}
noun1={this.state.value2}
properName2={this.state.value3}
properName3={this.state.value4}
noun2={this.state.value5}
personsName1={this.state.value6}
noun3={this.state.value7}
/>
</div>
);
}
return (
<div>
<div style={divStyle}>
<form onSubmit={this.handleSubmit}>
<label>
Proper Name:
<input
name="input1"
type="text"
value={this.state.value1}
onChange={this.handleFirstChange}
/>
</label>
<label>
Noun:
<input
name="input2"
type="text"
value={this.state.value2}
onChange={this.handleSecondChange}
/>
</label>
<label>
Another Proper Name:
<input
name="input3"
type="text"
value={this.state.value3}
onChange={this.handleThirdChange}
/>
</label>
<label>
And Another Proper Name:
<input
name="input4"
type="text"
value={this.state.value4}
onChange={this.handleFourthChange}
/>
</label>
<label>
Noun:
<input
name="input5"
type="text"
value={this.state.value5}
onChange={this.handleFifthChange}
/>
</label>
<label>
Person's Name:
<input
name="input6"
type="text"
value={this.state.value6}
onChange={this.handleSixthChange}
/>
</label>
<label>
Another Noun:
<input
name="input7"
type="text"
value={this.state.value7}
onChange={this.handleSeventhChange}
/>
</label>
<input type="submit" value="Submit" />
</form>
</div>
<NextQuestion>
{question}
</NextQuestion>
</div>
);
}
}
export default NameForm;
我使用这个练习教我更多关于React和条件的知识。谢谢你的帮助。
答案 0 :(得分:1)
首先,您需要创建一个问题列表:>>> a.astype(int, value_on_error=0)
array
您可以通过设置数组的const QuestionsList = [
{
// Your question title
q: "Are you a human?",
// Validate the user answer
a: (answer) => (answer === 'yes'),
// Force user to give a correct answer
required: true
// Add more properties
...
},
...
];
的问题进行导航:
index
当用户输入文本并点击提交时,文本输入将被隐藏(但不会删除或删除,因为输入的值用于传递道具),并且显示带有新输入的下一个文本输入,直到。
由于您只使用了输入this.state = { current: 0 }
...
// Select current question
QuestionList[this.state.current]
// Select next question
QuestionList[this.state.current + 1]
// Select last question
QuestionList[QuestionList.length - 1]
,因此您可以在所有问题中使用单个组件,而无需在此处理[text]
:
conditionals
React会通过 const RenderQuestion = (
<div>
<h2>{question.q}</h2>
<input type="text"
value={this.state.value}
onChange={this.handleChange}
/>
<button onClick={this.handleSubmit}>
Submit
</button>
</div>
);
更新组件内容
这会产生state
因为this.props和this.state可以异步更新,所以你不应该依赖它们的值来计算下一个状态
要解决此问题,请使用hide previous / show next
的第二种形式:
setState
请参阅:State Updates May Be Asynchronous
当回答完所有问题后,将调用Madlibs组件。
this.setState(prev => {
// Get previous state
const {value, current} = prev;
//If input not empty
if (value.length > 0) {
// Validate answer: true / false
const validation = questions[current].a(value);
//If not last question
return (prev.current < index) ?
//Select next question / reset input
{
current: prev.current + 1,
value:''
} :
// else: Completed!
{ completed: true };
}
});
如果条件为真,那么元素就在&amp;&amp;将出现在输出中。如果是假,React将忽略并跳过它。
{ this.state.completed ? <Madlibs /> : RenderQuestion }
有条件地呈现内联元素的另一种方法是使用JavaScript条件运算符:
condition === true && element / method
请参阅:Inline If with Logical && Operator
condition ? true : false
&#13;
const QuestionsList = [
{
q: "What's your name?",
a: (answer) => /^[A-Za-z\s]+$/.test(answer),
// Force user to give a correct answer
required: true
},
{
q: "Type a color:",
a: (answer) => {
const colors = ['blue', 'green', 'red', 'yellow', 'black', 'brown', 'orange', 'pink', 'purple', 'white', 'gray']
return colors.includes(answer);
},
required: true
},
];
class Questionary extends React.Component {
constructor(props){
super(props);
//Init state
this.state = {
current: 0,
value:'',
completed: false,
data: []
};
// Bind handlers
this.handleSubmit = this.handleSubmit.bind(this);
this. handleChange = this.handleChange.bind(this);
}
handleChange(event) {
this.setState({value: event.target.value});
}
handleSubmit () {
const {questions} = this.props;
const index = questions.length - 1 ;
let state = {};
this.setState(prev => {
// Vars
const { value, current } = prev;
const question = questions[current];
const validation = question.a(value);
//If input not empty
if (value.length > 0) {
// Debug validation
!validation && console.log("Please enter a valid value!");
//Force user to give the correct answer)
if (question.required && validation == false) return state;
// Data for the template string
let data = prev.data;
data.push(value);
//If not last question
state = (prev.current < index) ?
//Select next question and reset input
{
current: prev.current + 1,
value:'',
data
} :
// else: Completed!
{ completed: true, data };
return state;
}
// Debug input
console.log("Empty input!");
});
}
render() {
// Get all questions
const { questions } = this.props;
//Select question
const question = questions[this.state.current];
// Question component
const RenderQuestion = (
<div>
<h2>{question.q}</h2>
<input type="text"
value={this.state.value}
onChange={this.handleChange}
/>
<button onClick={this.handleSubmit}>
Submit
</button>
</div>
);
// Score component
const RenderTemplates = (
<div>
<h2>Completed!</h2>
<p>
This is the story of
<span>{this.state.data[0]}</span>
and how the
<span>{this.state.data[1]}</span> dragon...
</p>
<p>
<span>{this.state.data[0]}</span> found a
<span>{this.state.data[1]}</span> goblin in the woods and then...
</p>
</div>
);
return (
<div>
{
this.state.completed ?
RenderTemplates : RenderQuestion
}
</div>
);
}
}
ReactDOM.render(<Questionary questions={QuestionsList}/>, document.getElementById("root"));
&#13;
#root {
font-family: Arial, sans-serif;
color: #252525
}
h2, input[type=text] {
margin: 10px;
}
button {
border: 0;
border-radius: 3px;
background: #416dea;
padding: 5px 10px;
color: #FFF;
font-weight: bold;
border-radius: 3px;
}
p {
padding: 10px;
background: #ddd;
}
p span {
padding: 2px 4px;
margin: 0 10px;
background: #FFF;
color: #416dea;
}
&#13;