【发布时间】:2019-08-10 16:12:40
【问题描述】:
在 Promise 的 catch 中设置状态时出现错误。在下面的示例中,Promise 的 catch 在 onClickSave() 方法中。我相信我得到了错误,因为我误解了我所在的this 上下文。这里我想使用this 来处理DialogUsersNewProps 类的内容。来自 Java,this 的行为有点不同,我过去已经对 JavaScript 感到困惑。我必须怎么做才能从被拒绝的 Promise 的 catch 中设置状态?
来自浏览器控制台的错误:
/home/myuser/Documents/myprog/administration2/node_modules/react-dom/cjs/react-dom.development.js:506 Warning: A component is changing an uncontrolled input of type text to be controlled. Input elements should not switch from uncontrolled to controlled (or vice versa). Decide between using a controlled or uncontrolled input element for the lifetime of the component.
in input (created by InputBase)
in div (created by InputBase)
in InputBase (created by Context.Consumer)
in WithFormControlContext(InputBase) (created by WithStyles(WithFormControlContext(InputBase)))
in WithStyles(WithFormControlContext(InputBase)) (created by Input)
in Input (created by WithStyles(Input))
in WithStyles(Input) (created by TextField)
in div (created by FormControl)
in FormControl (created by WithStyles(FormControl))
in WithStyles(FormControl) (created by TextField)
in TextField (created by DialogUsersNew)
in div (created by DialogContent)
in DialogContent (created by WithStyles(DialogContent))
in WithStyles(DialogContent) (created by DialogUsersNew)
in div (created by Paper)
in Paper (created by WithStyles(Paper))
in WithStyles(Paper) (created by DialogUsersNew)
in DialogUsersNew (created by DisplayUsers)
in DisplayUsers (created by DisplayChoice)
in DisplayChoice (created by DisplayMain)
in main (created by DisplayMain)
in div (created by DisplayMain)
in div (created by DisplayMain)
in DisplayMain (created by App)
in App
in AppContainer
失败的 TypeScript 类:
import {
Button,
DialogActions,
DialogContent,
Paper,
TextField,
Typography,
} from '@material-ui/core';
import * as React from 'react';
import { User } from '../../../data/model/user';
import { AddNewUserResponse } from '../../../data/services/add-new-user-response';
import { DialogMessage } from '../../dialogs/dialog-message';
export interface DialogUsersNewProps {
onClickSave(user: User): Promise<AddNewUserResponse>;
onClickAbort(): void;
}
export interface DialogUsersNewState {
savingErrorMessage: string;
}
export class DialogUsersNew extends React.Component<DialogUsersNewProps, DialogUsersNewState> {
private textFieldUsername: string;
private textFieldPassword: string;
public constructor(props: any) {
super(props);
this.state = {
savingErrorMessage: '',
};
}
public render() {
return <Paper>
{this.state.savingErrorMessage !== '' &&
<DialogMessage title='Saving error' content={this.state.savingErrorMessage} />
}
<DialogContent>
<Typography variant='h5'>New user</Typography>
<TextField label='Username'
value={this.textFieldUsername}
className='w-100 fieldMargin'
onChange={(e: any) => this.onChangeTextFieldUsername(e.target.value)}
margin='normal'/>
<TextField label='Password'
type='password'
value={this.textFieldPassword}
className='w-100 fieldMargin'
onChange={(e: any) => this.onChangeTextFieldPassword(e.target.value)}
margin='normal'/>
<DialogActions>
<Button onClick={() => this.props.onClickAbort()} color='primary'>Abort</Button>
<Button onClick={() => this.onClickSave()} color='primary' variant='contained'>Save</Button>
</DialogActions>
</DialogContent>
</Paper>;
}
private getUser(): User {
// Generate new user based on props and textfields.
return {
password: this.textFieldPassword,
username: this.textFieldUsername,
};
}
private onChangeTextFieldUsername(content: string) {
// Save textbox change.
this.textFieldUsername = content;
}
private onChangeTextFieldPassword(content: string) {
// Save textbox change.
this.textFieldPassword = content;
}
private onClickSave() {
// Send click save event to parent.
this.props.onClickSave(this.getUser()).then((response: AddNewUserResponse) => {
// Check if success has failed.
if (!response.success) {
// Save message in state.
if (response.message) {
this.setState({savingErrorMessage: response.message});
} else {
this.setState({savingErrorMessage: 'Undefined error.'});
}
}
}).catch((response: AddNewUserResponse) => {
// Save message in state.
if (response.message) {
this.setState({savingErrorMessage: response.message});
} else {
this.setState({savingErrorMessage: 'Undefined error.'});
}
});
}
}
【问题讨论】:
-
this在onClickSave的捕获中等于什么? -
你能把
onClickSave声明为箭头函数吗?private onClickSave = () => { ... -
@Nicholas 我不确定我是否正确理解了您的问题。
catch中的this指的是DialogUsersNew类中的方法。我正在尝试通过访问setState方法在DialogUsersNewState中设置状态。 -
我在私有函数中使用
this是错误的。它仅适用于static函数。 -
尝试使用前面提到的箭头函数。它将
this绑定到父作用域。
标签: reactjs typescript