【发布时间】:2019-09-23 02:06:40
【问题描述】:
我有一个注册页面,可以根据this.state 中的布尔值在两种形式之间切换。如果 bool == true 则显示个人注册表单,如果 == false 则显示业务注册表单。一次只能看到一个表格(我已经在这里工作了)。当我试图保留注册表单的状态时,我会感到困惑,而不管 bool 值如何。即,如果您开始填写个人表格并切换到业务表格,我不想丢失这些条目。我看到解决方案是将表单进度存储在注册页面的状态中。
我正在尝试提升每个 *SignUpForm 组件的状态,并在 this.state、personalForm 和 businessForm 的两个子对象中跟踪它们。但是,每当我输入文本时,例如,名字字段 TextInput 我都会收到一条错误消息:
TypeError: undefined is not an object (evalating 'form.first')
所以我很自然地开始在提升工作流程中放置console.log 语句,这是我尝试开始将数据输入表单后打印的内容:
Handling internal personal form change!
Lifting up:
undefined
Handling personal change in SignUp page
Existing personal form:
Object {
"email": "",
"first": "",
"last": "",
}
Updating personal form to:
undefined
Completed update, new personal form:
Object {
"email": "",
"first": "",
"last": "",
}
undefined
Rendering personal form!
undefined
Rendering personal form!
undefined
如您所见,我要提升的数据是undefined。我开始弄乱PersonalSignUpForm 中哪个组件具有onChange 方法。现在它是根 View 组件的一个道具,当然,它不起作用。我尝试将它放在实际的 TextInput 本身中,但仍然产生了相同的未定义错误。
所以,总而言之,我假设我的状态提升失败了,因为我的 *SignUpForm 组件不仅仅是一个组件/复合体,而且 React 无法推断出 e.target.value 是什么。如何更改我的提升代码以正确捕获对TextInput 的所有更改并将它们存储在 SignUp.js 的状态中?
SignUp.js
export default class SignUpScreen extends React.Component {
constructor(props){
super(props);
this._handlePersonalAccountPress = this._handlePersonalAccountPress.bind(this);
this._handleBusinessAccountPress = this._handleBusinessAccountPress.bind(this);
this._handlePersonalFormChange = this._handlePersonalFormChange.bind(this);
this._handleBusinessFormChange = this._handleBusinessFormChange.bind(this);
this.state = {
personalAccount: true,
personalForm: {
first: '',
last: '',
email: ''
},
businessForm: {
company: '',
email: ''
}
};
}
_handlePersonalAccountPress() {
this.setState({personalAccount: true})
}
_handleBusinessAccountPress() {
this.setState({personalAccount: false})
}
_handlePersonalFormChange(newForm) {
console.log('Handling personal change in SignUp page')
console.log('Existing personal form:')
console.log(this.state.personalForm)
console.log('Updating personal form to:')
console.log(newForm)
this.setState({personalForm: newForm})
console.log('Completed update, new personal form:')
console.log(this.state.personalForm)
}
render(){
if (this.state.personalAccount)
{
console.log(this.state.personalForm)
form = <PersonalSignUpForm
_onFormChange={this._handlePersonalFormChange}
form={this.state.personalForm}/>;
}
else
{
form = <BusinessSignUpForm
_onFormChange={this._handleBusinessFormChange}
form={this.state.businessForm}/>;
}
return (
<KeyboardAvoidingView behavior="padding">
<StatusBar barStyle="dark-content" />
<View>
<AccountTypeButton
text='Personal'
onAccountChange={this._handlePersonalAccountPress}
selected={this.state.personalAccount}/>
<AccountTypeButton
text='Business'
onAccountChange={this._handleBusinessAccountPress}
selected={!this.state.personalAccount}/>
</View>
{form}
<View>
<TouchableOpacity
onPress={() => this._onCreateAccountPress()}>
<Text>Create Account</Text>
</TouchableOpacity>
</View>
</KeyboardAvoidingView>
);
}
}
PersonalSignUpForm.js
BusinessSignUpForm.js 相同,只是 TextInput 不同
export default class PersonalSignUpForm extends Component {
constructor(props) {
super(props);
this.handleChange = this.handleChange.bind(this);
}
handleChange (e) {
console.log('Handling internal personal form change!')
console.log('Lifting up:')
console.log(e.target.value)
this.props._onFormChange(e.target.value);
}
render() {
console.log('Rendering personal form!')
console.log(this.props.form)
const form = this.props.form
return (
<View style={styles.forms}
onChange={this.handleChange}>
<View style={styles.textInputBorder}>
<TextInput style={styles.textInput}
value={form.first}
editable
placeholder='first name'/>
</View>
<View style={styles.textInputBorder}>
<TextInput style={styles.textInput}
value={form.last}
editable
placeholder='last name'/>
</View>
<View style={styles.textInputBorder}>
<TextInput style={styles.textInput}
value={form.email}
editable
placeholder='email'
keyboardType='email-address'/>
</View>
</View>
);
}
}
【问题讨论】:
-
如果你有类似CodeSandbox 的东西来演示发生了什么,那就太好了。
标签: javascript reactjs react-native