Javascript 使用setState方法添加子对象
我正在尝试使用Javascript 使用setState方法添加子对象,javascript,react-native,expo,Javascript,React Native,Expo,我正在尝试使用expo应用程序中的方法this.setState向现有对象添加新的子对象。单击按钮后将添加子对象,该按钮将更新构成子对象的字段 这是我的代码: import React, { Component } from 'react'; import { View, Text, StyleSheet, TouchableOpacity, ImageBackground } from 'react-native'; import CenteredButton from '../compon
expo
应用程序中的方法this.setState
向现有对象添加新的子对象。单击按钮后将添加子对象,该按钮将更新构成子对象的字段
这是我的代码:
import React, { Component } from 'react';
import { View, Text, StyleSheet, TouchableOpacity, ImageBackground } from 'react-native';
import CenteredButton from '../components/CenteredButton';
import { Actions } from 'react-native-router-flux';
var t = require('tcomb-form-native');
var _ = require('lodash');
const Form = t.form.Form;
const stylesheet = _.cloneDeep(t.form.Form.stylesheet);
stylesheet.textbox.normal.borderColor = '#b3b3b5';
stylesheet.textbox.normal.fontFamily = 'RobotoThin';
stylesheet.textbox.normal.backgroundColor = '#fdfdfd';
stylesheet.textbox.normal.fontSize = 18;
stylesheet.textbox.normal.borderWidth = 0.6;
stylesheet.textbox.normal.borderRadius = 10;
stylesheet.textbox.error.fontFamily = 'RobotoThin';
stylesheet.textbox.error.backgroundColor = '#fdfdfd';
stylesheet.textbox.error.fontSize = 18;
stylesheet.textbox.error.borderWidth = 0.6;
stylesheet.textbox.error.borderRadius = 10;
const Email = t.refinement(t.String, email => {
const regex = /[a-z0-9!#$%&'*+/=?^_`{|}~-]+(?:\.[a-z0-9!#$%&'*+/=?^_`{|}~-]+)*@(?:[a-z0-9](?:[a-z0-9-]*[a-z0-9])?\.)+[a-z0-9](?:[a-z0-9-]*[a-z0-9])?/;
return regex.test(email);
});
const EmailTo = t.struct({
emailPerson: Email,
emailInsurance: t.maybe(Email)
});
const options = {
auto: 'none',
stylesheet: stylesheet,
fields: {
emailPerson: {
placeholder: 'Email personale',
autoCapitalize: 'none',
autoCorrect: false,
},
emailInsurance: {
placeholder: 'Email Assicurazione',
autoCapitalize: 'none',
password: true,
}
}
}
export default class NessunProblema extends Component {
constructor(props) {
super(props);
this.state = {
emails: {
emailPerson: '',
emailInsurance: ''
},
ascertainment: { }
}
}
componentDidMount() {
this.setState({ ascertainment: this.props.ascertainment });
}
_onChange = (emails) => {
this.setState({ emails });
}
_handle = () => {
const value = this.refs.form.getValue();
if ( value ) {
this.setState(prev => ({
ascertainment: {
...prev.ascertainment,
emails: {
...prev.ascertainment.emails,
emailPerson: value.emailPerson,
emailInsurance: value.emailInsurance
}
}
}));
}
console.log(this.state.emails);
console.log(this.state.ascertainment);
}
render() {
return (
<View style={{flex: 1, backgroundColor: 'white' }}>
<ImageBackground source={require('../images/NoProblem.png')} style={styles.backgroundImage}>
<View style={{ flex: 2, alignItems: 'center', justifyContent: 'center', width: '100%', paddingHorizontal: 20, top: 10}}>
<Text style={styles.domanda}>
Text
</Text>
<Text style={styles.domanda2}>
Text
</Text>
</View>
<View style={{padding: 20}}>
<Form
ref='form'
options={options}
type={EmailTo}
value={this.state.emails}
onChange={this._onChange}
/>
</View>
<CenteredButton
next={ this._handle }
/>
</ImageBackground>
</View>
)
}
}
const styles = StyleSheet.create({
domanda: {
color: '#00b0ff',
textAlign: 'center',
fontSize: 44,
fontFamily: 'RobotoRegular',
alignItems: 'center',
justifyContent: 'center',
padding: 20
},
domanda2: {
color: 'black',
textAlign: 'center',
fontSize: 22,
fontFamily: 'RobotoRegular',
alignItems: 'center',
justifyContent: 'center',
padding: 20
},
testoRosso: {
color: '#f32a19',
fontFamily: 'RobotoRegular',
},
backgroundImage: {
flex: 1,
resizeMode: 'cover'
},
textInput: {
width: '100%',
paddingHorizontal: 15,
height: 40,
marginBottom: 20,
fontSize: 18,
borderWidth: 0.6,
borderColor: 'black',
borderRadius: 10,
color: 'black',
fontFamily: 'RobotoThin',
backgroundColor: 'white'
},
});
import React,{Component}来自'React';
从“react native”导入{视图、文本、样式表、TouchableOpacity、ImageBackground};
从“../components/CenteredButton”导入CenteredButton;
从“react native router flux”导入{Actions};
var t=require('tcomb-form-native');
var=要求('lodash');
const Form=t.Form.Form;
const stylesheet=\ u0.cloneDeep(t.form.form.stylesheet);
stylesheet.textbox.normal.borderColor='#b3b5';
stylesheet.textbox.normal.fontFamily='RobotoThin';
stylesheet.textbox.normal.backgroundColor='#fdfdfd';
stylesheet.textbox.normal.fontSize=18;
stylesheet.textbox.normal.borderWidth=0.6;
stylesheet.textbox.normal.borderRadius=10;
stylesheet.textbox.error.fontFamily='RobotoThin';
stylesheet.textbox.error.backgroundColor='#fdfdfd';
stylesheet.textbox.error.fontSize=18;
stylesheet.textbox.error.borderWidth=0.6;
stylesheet.textbox.error.borderRadius=10;
const Email=t.definition(t.String,Email=>{
常量正则表达式=/[a-z0-9!#$%&'*+/=?(?:\.[a-z0-9!#$%&'*+/=?([a-z0-9](?:[a-z0-9-][a-z0-9-][a-z0-9-][a-z0 a-9-][a-z0 a-9-][a-z0 a-9]。+[a-z0;
返回正则表达式测试(电子邮件);
});
const EmailTo=t.struct({
emailPerson:Email,
emailInsurance:t.maybe(电子邮件)
});
常量选项={
自动:“无”,
样式表:样式表,
字段:{
电子邮件发送人:{
占位符:“电子邮件个人”,
自动资本化:“无”,
自动更正:错误,
},
电子邮件保险:{
占位符:“电子邮件助理”,
自动资本化:“无”,
密码:true,
}
}
}
导出默认类NessUnproblem扩展组件{
建造师(道具){
超级(道具);
此.state={
电子邮件:{
emailPerson:“”,
电子邮件保险:“”
},
确定:{}
}
}
componentDidMount(){
this.setState({assecution:this.props.assecution});
}
_onChange=(电子邮件)=>{
this.setState({emails});
}
_句柄=()=>{
常量值=this.refs.form.getValue();
如果(值){
this.setState(prev=>({
确定:{
…先前的确定,
电子邮件:{
…上一次确认电子邮件,
emailPerson:value.emailPerson,
emailInsurance:value.emailInsurance
}
}
}));
}
console.log(this.state.emails);
控制台日志(此状态确定);
}
render(){
返回(
正文
正文
)
}
}
const styles=StyleSheet.create({
多曼达:{
颜色:“#00b0ff”,
textAlign:'中心',
尺码:44,
fontFamily:“机器人神经”,
对齐项目:“居中”,
为内容辩护:“中心”,
填充:20
},
领域2:{
颜色:'黑色',
textAlign:'中心',
尺寸:22,
fontFamily:“机器人神经”,
对齐项目:“居中”,
为内容辩护:“中心”,
填充:20
},
Testoroso:{
颜色:“#f32a19”,
fontFamily:“机器人神经”,
},
背景图片:{
弹性:1,
resizeMode:“封面”
},
文本输入:{
宽度:“100%”,
水平方向:15,
身高:40,
marginBottom:20,
尺码:18,
边框宽度:0.6,
边框颜色:“黑色”,
边界半径:10,
颜色:'黑色',
fontFamily:“RobotoThin”,
背景颜色:“白色”
},
});
我注意到,如果我点击两次按钮,就会得到正确的结果。但是,为什么
我遵循这一点,但没有解决问题。问题是setState()不同步,值是异步更新的 setState()不会立即改变this.state,但会创建挂起的状态转换。调用此方法后访问this.state可能会返回现有值。无法保证对setState调用的同步操作,并且可能会对调用进行批处理以提高性能 当
console.log(this.state.emails)
运行时,它会连续打印正确的文件。我怎样才能解决这个问题?
_handle = () => {
const value = this.refs.form.getValue();
if ( value ) {
this.setState(prev => ({
ascertainment: {
...prev.ascertainment,
emails: {
...prev.ascertainment.emails,
emailPerson: value.emailPerson,
emailInsurance: value.emailInsurance
}
}
}));
}
console.log(this.state.emails); // will be the emails in the previous state, since setState has not been called yet by react
console.log(this.state.ascertainment); // if you click twice, you are still getting the `last` state, but since it is the same as the state you are setting the second time, you get the wrong idea that it is being set if you click twice!
}