因此,我遇到以下问题,我试图显示用户在用户个人资料中发表的所有帖子。如果我从登录开始并转到配置文件,则会出现以下错误:this.props.user [0] .id未定义。但是,如果刷新页面(有时刷新两次),则效果很好。
我已经在线搜索过,只能看到相反的情况(刷新时道具未定义),我找不到解决方案。
这是我的代码:
import React from "react";
import axios from "axios";
import { Card, CardBody, CardTitle, CardText} from "reactstrap";
import Withuser from "./Withuser"
class Profile extends React.Component {
constructor(props) {
super(props)
this.state = {
thoughts: []
}
}
componentDidMount = () => {
this.getShares()
}
getShares = () => {
const user_id = this.props.user[0].id
console.log(this.props.user[0].id)
axios(`http://localhost:7001/api/profile/shares/${user_id}`)
.then(res => {
console.log(res.data)
this.setState(state => ({
thoughts: res.data,
loggedIn: !state.loggedIn
}))
})
.catch(error => {
this.setState({ error: true })
})
}
render() {
const { thoughts } = this.state
return(
<div>
<h1>Your posts</h1>
<ul>
{thoughts.map((thought, index) => {
return (
<Card className='thoughts' key={index}>
<CardBody>
<CardTitle>{thought.user_name} posted at {thought.createdAt}</CardTitle>
<CardText>{thought.body}</CardText>
</CardBody>
</Card>
)
})}
</ul>
</div>
)
}
}
export default Withuser(Profile, { renderNull: true });
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.6.3/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.6.3/umd/react-dom.production.min.js"></script>
Withuser组件:
import React, { useState, useEffect } from 'react'
import axios from 'axios'
const withUser = (Component, options = { renderNull: true }) => props => {
const [userData, setUserData] = useState(null)
const [userId, setUserId] = useState(null)
const [error, setError] = useState(false)
useEffect(() => {
const token = localStorage.getItem('token')
if (!token) return
axios('http://localhost:7001/api/profile', {
headers: {
'x-access-token': token,
},
})
.then(response => {
const id = response.data.id
setUserId(id)
})
.catch(error => {
setError(true)
console.log(error)
})
}, [])
useEffect(() => {
axios(`http://localhost:7001/api/users/${userId}`)
.then(response => {
setUserData(response.data)
})
}, [userId])
if (!userData && options.renderNull) return null
return <Component {...props} user={userData} />
}
export default withUser
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.6.3/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.6.3/umd/react-dom.production.min.js"></script>
您能看到错误在哪里吗?
任何帮助将不胜感激:)
答案 0 :(得分:0)
可以通过在HOC中添加加载状态来解决此问题,以便在获取数据之前不呈现包装的组件。
const withUser = (Component, options = { renderNull: true }) => props => {
const [userData, setUserData] = useState(null);
const [userId, setUserId] = useState(null);
const [error, setError] = useState(false);
const [loading, setLoading] = useState(false);
useEffect(() => {
const token = localStorage.getItem('token');
if (!token) return;
setLoading(true); // set the loading state before api call is made
axios('http://localhost:7001/api/profile', {
headers: {
'x-access-token': token,
},
})
.then(response => {
const id = response.data.id;
setUserId(id);
})
.catch(error => {
setError(true);
console.log(error);
})
.finally(() => {
setLoading(false); // reset loading state after api call is done
});
}, []);
useEffect(() => {
setLoading(true); // set the loading state before api call is made
axios(`http://localhost:7001/api/users/${userId}`).then(response => {
setUserData(response.data);
}).finally(() => setLoading(false)); // reset loading state after api call is done
}, [userId]);
if (loading) return null; // Or render a loading indicator
if (!userData && options.renderNull) return null;
return <Component {...props} user={userData} />;
};
答案 1 :(得分:0)
这是因为在useEffect中,axios是一个异步调用,
const withUser = (Component, options = { renderNull: true }) => props => {
...
useEffect(() => {
axios(`http://localhost:7001/api/users/${userId}`)
.then(response => {
setUserData(response.data)
})
}, [userId])
快速可靠的解决方案是在Profile组件上添加默认道具
Profile.defaultProps = {
user: [],
}
并必须检查
getShares = () => {
if(props.user.length === 0) return