道具未及时加载 AJAX 请求
Props not loading in time for AJAX request
我检查了几个类似的问题并尝试实现他们的答案,但仍然没有成功。这是代码:
import React, {Component, Fragment} from "react";
import Files from "./client/files";
import axios from "axios";
const styles = {
card: {
border: "1px solid transparent",
borderRadius: "8px",
padding: "20px",
boxShadow: "0 1px 2px 0 rgba(60,64,67,0.302), 0 2px 6px 2px rgba(60,64,67,0.149)",
maxWidth: "75%"
},
h1: {
marginTop: "30px"
},
link: {
color: '#000'
},
i: {
fontSize: '24px',
margin: '0 20px'
},
h4: {
color: "#24486f",
letterSpacing: "1.2px"
},
h5: {
color: "#24486f",
letterSpacing: "1.2px"
}
}
class Client extends Component {
constructor() {
super();
this.state = {
client_files: [],
user_id: "",
client_name: "",
version_ref: "",
first_name: "",
last_name: "",
email: "",
phone: "",
website: "",
file_refs: []
};
this.getFileData = this.getFileData.bind(this);
}
componentDidMount() {
console.log(this.props.currentUser)
this.getFileData();
}
getFileData() {
let fileRefs = this.props.currentUser.file_refs;
let fileData = [];
for (let i = 0; i < fileRefs.length; i++) {
axios.get("/api/file/get-file/" + fileRefs[i])
.then( res => {
console.log(res.data.response)
fileData.push(res.data.response);
this.setState({
client_files: fileData
})
})
.catch( err => console.log(err.response.data))
}
}
render() {
return(
<Fragment>
<div className="container">
<div className="row">
<div className="col-lg-12">
<h1 style={styles.h1}> PartnerPortal </h1>
<hr/>
<h4 style={styles.h4}>
<em>Welcome, {this.props.currentUser.first_name} {this.props.currentUser.last_name}</em>
</h4>
<h5 style={styles.h5}>
<em>{ this.props.currentUser.client_name}</em>
</h5>
<hr/>
<p> PartnerPortal allows you quick access to files, resources, and other documents that are part of your current contract with .... Company</p>
<div style={styles.card}>
<table className="table">
<thead>
<tr>
<th scope="col">#</th>
<th scope="col">Type</th>
<th scope="col">File Name</th>
</tr>
</thead>
<tbody>
{this.state.client_files.map(( file, i ) => (
<tr key={i}>
<td>{i}</td>
<td style={styles.p}>
{ file.file_type === "PDF" &&
<a href={file.file_url}><span style={styles.link}><i style={styles.i} className="far fa-file-pdf"></i></span></a>
}
{ file.file_type === "DOC" &&
<a href={file.file_url}><span style={styles.link}><i style={styles.i} className="far fa-file-alt"></i></span></a>
}
{ file.file_type === "Directory" &&
<a href={file.file_url}><span style={styles.link}><i style={styles.i} className="far fa-folder"></i></span></a>
}
{ file.file_type === "Presentation" &&
<a href={file.file_url}><span style={styles.link}><i style={styles.i} className="far fa-file-powerpoint"></i></span></a>
}
</td>
<td>{file.file_name}</td>
</tr>
))}
</tbody>
</table>
</div>
</div>
</div>
</div>
</Fragment>
);
}
}
export default Client;
currentUser 作为属性从父组件传递下来,并包含一个文件引用数组 (this.props.currentUser.file_refs)。 componentDidMount()
中的 console.log
准确地将所有文件引用记录到控制台。然而,当getFileData()
函数运行时,它returns错误:TypeError: Cannot read property 'length' of undefined
.
我已经尝试过的:
- 更改为 componentWillMount()
- 在我的 componentDidMount()
函数中添加 if (this.props.currentUser){this.getFileData())
- 添加 if (!this.props.currentUser.file_refs) { return null ) return ( <Fragment> ..... </Fragment>
有人知道我做错了什么吗?
编辑:从父组件添加路由,Main.js
{ (isLoggedIn && currentUser.isAdmin) &&
<Route exact path="/" render={() => (<IodDash currentUser={this.props.currentUser}/>)}/>
}
{ (isLoggedIn && !currentUser.isAdmin) &&
<Route exact path="/" render={() => (<ClientDash currentUser={this.props.currentUser}/>)}/>
}
看起来 this.props.currentUser.file_refs
在将其设置为函数 getFileData()
中的 fileRefs
变量之前未完全加载,这就是为什么您收到错误 TypeError: Cannot read property 'length' of undefined
.您可能想在父组件中编写一个检查,以确保在将 prop 传递给子组件之前加载数据。
我检查了几个类似的问题并尝试实现他们的答案,但仍然没有成功。这是代码:
import React, {Component, Fragment} from "react";
import Files from "./client/files";
import axios from "axios";
const styles = {
card: {
border: "1px solid transparent",
borderRadius: "8px",
padding: "20px",
boxShadow: "0 1px 2px 0 rgba(60,64,67,0.302), 0 2px 6px 2px rgba(60,64,67,0.149)",
maxWidth: "75%"
},
h1: {
marginTop: "30px"
},
link: {
color: '#000'
},
i: {
fontSize: '24px',
margin: '0 20px'
},
h4: {
color: "#24486f",
letterSpacing: "1.2px"
},
h5: {
color: "#24486f",
letterSpacing: "1.2px"
}
}
class Client extends Component {
constructor() {
super();
this.state = {
client_files: [],
user_id: "",
client_name: "",
version_ref: "",
first_name: "",
last_name: "",
email: "",
phone: "",
website: "",
file_refs: []
};
this.getFileData = this.getFileData.bind(this);
}
componentDidMount() {
console.log(this.props.currentUser)
this.getFileData();
}
getFileData() {
let fileRefs = this.props.currentUser.file_refs;
let fileData = [];
for (let i = 0; i < fileRefs.length; i++) {
axios.get("/api/file/get-file/" + fileRefs[i])
.then( res => {
console.log(res.data.response)
fileData.push(res.data.response);
this.setState({
client_files: fileData
})
})
.catch( err => console.log(err.response.data))
}
}
render() {
return(
<Fragment>
<div className="container">
<div className="row">
<div className="col-lg-12">
<h1 style={styles.h1}> PartnerPortal </h1>
<hr/>
<h4 style={styles.h4}>
<em>Welcome, {this.props.currentUser.first_name} {this.props.currentUser.last_name}</em>
</h4>
<h5 style={styles.h5}>
<em>{ this.props.currentUser.client_name}</em>
</h5>
<hr/>
<p> PartnerPortal allows you quick access to files, resources, and other documents that are part of your current contract with .... Company</p>
<div style={styles.card}>
<table className="table">
<thead>
<tr>
<th scope="col">#</th>
<th scope="col">Type</th>
<th scope="col">File Name</th>
</tr>
</thead>
<tbody>
{this.state.client_files.map(( file, i ) => (
<tr key={i}>
<td>{i}</td>
<td style={styles.p}>
{ file.file_type === "PDF" &&
<a href={file.file_url}><span style={styles.link}><i style={styles.i} className="far fa-file-pdf"></i></span></a>
}
{ file.file_type === "DOC" &&
<a href={file.file_url}><span style={styles.link}><i style={styles.i} className="far fa-file-alt"></i></span></a>
}
{ file.file_type === "Directory" &&
<a href={file.file_url}><span style={styles.link}><i style={styles.i} className="far fa-folder"></i></span></a>
}
{ file.file_type === "Presentation" &&
<a href={file.file_url}><span style={styles.link}><i style={styles.i} className="far fa-file-powerpoint"></i></span></a>
}
</td>
<td>{file.file_name}</td>
</tr>
))}
</tbody>
</table>
</div>
</div>
</div>
</div>
</Fragment>
);
}
}
export default Client;
currentUser 作为属性从父组件传递下来,并包含一个文件引用数组 (this.props.currentUser.file_refs)。 componentDidMount()
中的 console.log
准确地将所有文件引用记录到控制台。然而,当getFileData()
函数运行时,它returns错误:TypeError: Cannot read property 'length' of undefined
.
我已经尝试过的:
- 更改为 componentWillMount()
- 在我的 componentDidMount()
函数中添加 if (this.props.currentUser){this.getFileData())
- 添加 if (!this.props.currentUser.file_refs) { return null ) return ( <Fragment> ..... </Fragment>
有人知道我做错了什么吗?
编辑:从父组件添加路由,Main.js
{ (isLoggedIn && currentUser.isAdmin) &&
<Route exact path="/" render={() => (<IodDash currentUser={this.props.currentUser}/>)}/>
}
{ (isLoggedIn && !currentUser.isAdmin) &&
<Route exact path="/" render={() => (<ClientDash currentUser={this.props.currentUser}/>)}/>
}
看起来 this.props.currentUser.file_refs
在将其设置为函数 getFileData()
中的 fileRefs
变量之前未完全加载,这就是为什么您收到错误 TypeError: Cannot read property 'length' of undefined
.您可能想在父组件中编写一个检查,以确保在将 prop 传递给子组件之前加载数据。