在状态中存储对象时渲染中的 ReactJS 获取类型错误
ReactJS Fetch Type error in render when storing an object in state
我对反应很陌生,我正在尝试从服务器获取对象(会话)并使用表单对其进行编辑,并在进行更改后使用 post 将其存储到服务器。
我制作了一个从服务器获取数据并将其存储到状态中的组件。
问题是渲染部分出错,因为它可能还不知道状态对象的子字段。我指的是 'session.name' 和其他几个字段,但这会出错。 (TypeError: this.state.session 为空[更多信息])
class SessionFirstTab extends React.Component {
constructor() {
super();
this.state = {
session: null,
statechanged: false
};
this.handleChange = this.handleChange.bind(this);
this.handleSubmit = this.handleSubmit.bind(this);
this.getSessionData = this.getSessionData.bind(this)
}
componentDidMount() {
this.getSessionData()
}
getSessionData() {
var myHeaders = new Headers();
myHeaders.append("Content-Type", 'application/x-www-form-urlencoded');
myHeaders.append("x-access-token", 'eyJhbGciOiJIUzI1....');
myHeaders.append("userid", "5904ab94835a710868d19fa2");
myHeaders.append("id", this.props.sessionid);
var myInit = { method: 'GET',
headers: myHeaders,
mode: 'cors',
cache: 'default' };
fetch('http://localhost:3000/api/session',myInit)
.then(function(response) {
if (response.status !== 200) {
console.log('Looks like there was a problem. Status Code: ' +
response.status);
return;
}
// Examine the text in the response
response.json().then(function(data) {
data => this.setState({session: data});
});
}
)
.catch(function(err) {
console.log('Fetch Error', err);
});
} //////////////END getSessionInfo
handleChange(event) {
const target = event.target;
const value = target.type === 'checkbox' ? target.checked : target.value;
const name = target.name;
this.setState({ statechanged: true});
this.setState({session: {[name]: value}});
}
handleSubmit(event) {
// console.log(this.state.session.name);
event.preventDefault();
}
render() {
return (
<article className="article">
<h2 className="article-title">Edit Session </h2>
<section className="box box-default">
<div className="box-body padding-xl">
<section className="box box-default">
<div className="box-body no-padding">
<Tabs>
<Tab label="Properties" >
<div style={styles}>
<form role="form" onSubmit={this.handleSubmit}>
<div className="divider divider-lg" />
<div className="row">
<div className="col-xl-6">
<div className="box box-default">
<div className="box-body">
<div className="icon-box ibox-center">
<div className="ibox-icon">
<a href="javascript:;"><i className="material-icons">settings</i></a>
</div>
<h3>General</h3>
<div className="form-group">
<TextField name="name" id="name" hintText="Give this session a description" floatingLabelText="Name" floatingLabelFixed defaultValue={this.state.session.name} onChange={this.handleChange}/><br />
</div>
你只需要在session为null时处理即可。一个简单的解决方案是:
render() {
const session_name = this.state.session.name || '';
return (
<article className="article">
<h2 className="article-title">Edit Session </h2>
<section className="box box-default">
<div className="box-body padding-xl">
<section className="box box-default">
<div className="box-body no-padding">
<Tabs>
<Tab label="Properties" >
<div style={styles}>
<form role="form" onSubmit={this.handleSubmit}>
<div className="divider divider-lg" />
<div className="row">
<div className="col-xl-6">
<div className="box box-default">
<div className="box-body">
<div className="icon-box ibox-center">
<div className="ibox-icon">
<a href="javascript:;"><i className="material-icons">settings</i></a>
</div>
<h3>General</h3>
<div className="form-group">
<TextField name="name" id="name" hintText="Give this session a description" floatingLabelText="Name" floatingLabelFixed defaultValue={session_name} onChange={this.handleChange}/><br />
</div>
我认为您唯一需要做的就是检查会话是否为空。
我通常使用两种方法,总是取决于我的需要。
方法一:
如果有会话,渲染session.name,否则渲染一个空字符串。
<TextField name="name" id="name" hintText="Give this session a description" floatingLabelText="Name" floatingLabelFixed defaultValue={this.state.session !== null ? this.state.session.name : ''} onChange={this.handleChange}/>
这种方式会强制您在处理程序内部进行检查。在您的情况下,您将必须检查 handleChange 内部以及 handleSummit 中。
所以在我看来,你应该尝试第二种方法。
方法二:
如果有会话,则呈现表单,否则呈现一些加载图
if(this.state.session){
return (
<form role="form" onSubmit={this.handleSubmit}>
... your staff here
</form>
);
} else {
return (
<div>
We are waiting for the session
</div>
);
}
特别是,我不会将整个会话存储在状态中,而是只存储我需要的属性。我的意思是,我会存储 this.state.name。仅出于语义和责任方面的考虑。为什么?我假设你的会话有很多组件不需要知道的东西,所以它不应该在那里。但我们可以好好讨论一下。
希望对您有所帮助,如果您觉得需要澄清,请告诉我,我会提供帮助。
我对反应很陌生,我正在尝试从服务器获取对象(会话)并使用表单对其进行编辑,并在进行更改后使用 post 将其存储到服务器。
我制作了一个从服务器获取数据并将其存储到状态中的组件。
问题是渲染部分出错,因为它可能还不知道状态对象的子字段。我指的是 'session.name' 和其他几个字段,但这会出错。 (TypeError: this.state.session 为空[更多信息])
class SessionFirstTab extends React.Component {
constructor() {
super();
this.state = {
session: null,
statechanged: false
};
this.handleChange = this.handleChange.bind(this);
this.handleSubmit = this.handleSubmit.bind(this);
this.getSessionData = this.getSessionData.bind(this)
}
componentDidMount() {
this.getSessionData()
}
getSessionData() {
var myHeaders = new Headers();
myHeaders.append("Content-Type", 'application/x-www-form-urlencoded');
myHeaders.append("x-access-token", 'eyJhbGciOiJIUzI1....');
myHeaders.append("userid", "5904ab94835a710868d19fa2");
myHeaders.append("id", this.props.sessionid);
var myInit = { method: 'GET',
headers: myHeaders,
mode: 'cors',
cache: 'default' };
fetch('http://localhost:3000/api/session',myInit)
.then(function(response) {
if (response.status !== 200) {
console.log('Looks like there was a problem. Status Code: ' +
response.status);
return;
}
// Examine the text in the response
response.json().then(function(data) {
data => this.setState({session: data});
});
}
)
.catch(function(err) {
console.log('Fetch Error', err);
});
} //////////////END getSessionInfo
handleChange(event) {
const target = event.target;
const value = target.type === 'checkbox' ? target.checked : target.value;
const name = target.name;
this.setState({ statechanged: true});
this.setState({session: {[name]: value}});
}
handleSubmit(event) {
// console.log(this.state.session.name);
event.preventDefault();
}
render() {
return (
<article className="article">
<h2 className="article-title">Edit Session </h2>
<section className="box box-default">
<div className="box-body padding-xl">
<section className="box box-default">
<div className="box-body no-padding">
<Tabs>
<Tab label="Properties" >
<div style={styles}>
<form role="form" onSubmit={this.handleSubmit}>
<div className="divider divider-lg" />
<div className="row">
<div className="col-xl-6">
<div className="box box-default">
<div className="box-body">
<div className="icon-box ibox-center">
<div className="ibox-icon">
<a href="javascript:;"><i className="material-icons">settings</i></a>
</div>
<h3>General</h3>
<div className="form-group">
<TextField name="name" id="name" hintText="Give this session a description" floatingLabelText="Name" floatingLabelFixed defaultValue={this.state.session.name} onChange={this.handleChange}/><br />
</div>
你只需要在session为null时处理即可。一个简单的解决方案是:
render() {
const session_name = this.state.session.name || '';
return (
<article className="article">
<h2 className="article-title">Edit Session </h2>
<section className="box box-default">
<div className="box-body padding-xl">
<section className="box box-default">
<div className="box-body no-padding">
<Tabs>
<Tab label="Properties" >
<div style={styles}>
<form role="form" onSubmit={this.handleSubmit}>
<div className="divider divider-lg" />
<div className="row">
<div className="col-xl-6">
<div className="box box-default">
<div className="box-body">
<div className="icon-box ibox-center">
<div className="ibox-icon">
<a href="javascript:;"><i className="material-icons">settings</i></a>
</div>
<h3>General</h3>
<div className="form-group">
<TextField name="name" id="name" hintText="Give this session a description" floatingLabelText="Name" floatingLabelFixed defaultValue={session_name} onChange={this.handleChange}/><br />
</div>
我认为您唯一需要做的就是检查会话是否为空。 我通常使用两种方法,总是取决于我的需要。
方法一:
如果有会话,渲染session.name,否则渲染一个空字符串。
<TextField name="name" id="name" hintText="Give this session a description" floatingLabelText="Name" floatingLabelFixed defaultValue={this.state.session !== null ? this.state.session.name : ''} onChange={this.handleChange}/>
这种方式会强制您在处理程序内部进行检查。在您的情况下,您将必须检查 handleChange 内部以及 handleSummit 中。 所以在我看来,你应该尝试第二种方法。
方法二:
如果有会话,则呈现表单,否则呈现一些加载图
if(this.state.session){
return (
<form role="form" onSubmit={this.handleSubmit}>
... your staff here
</form>
);
} else {
return (
<div>
We are waiting for the session
</div>
);
}
特别是,我不会将整个会话存储在状态中,而是只存储我需要的属性。我的意思是,我会存储 this.state.name。仅出于语义和责任方面的考虑。为什么?我假设你的会话有很多组件不需要知道的东西,所以它不应该在那里。但我们可以好好讨论一下。
希望对您有所帮助,如果您觉得需要澄清,请告诉我,我会提供帮助。