React -typeError:无法读取未定义的属性
这是我的第一篇文章。我是新手反应和通过教程学习的。我用加载删除了不需要的零件,我会得到一个空白的站点和错误的类型:无法读取未定义的属性(读取'fullname')。
我已经搜索了一些解决方案并测试了一切,但它无法解决。将创建订单,但只有页面不会显示。
我真的很想了解为什么会发生这种情况以及如何解决此问题。
function reducer(state, action) {
switch (action.type) {
case 'FETCH_REQUEST': // Deleted
return { ...state, loading: true, error: '' }; // Deleted
case 'FETCH_SUCCESS':
return { ...state, loading: false, order: action.payload, error: '' };
case 'FETCH_FAIL':
return { ...state, loading: false, error: action.payload };
default:
return state;
}
}
export default function OrderScreen() {
const { state } = useContext(Store);
const { userInfo } = state;
const params = useParams();
const { id: orderId } = params;
const navigate = useNavigate();
const [{ loading , error, order }, dispatch] = useReducer(reducer, { // Deleted "loading"
loading: true, // Deleted "loading: true"
order: {},
error: '',
});
useEffect(() => {
const fetchOrder = async () => {
try {
dispatch({ type: 'FETCH_REQUEST' }); // Deleted
const { data } = await axios.get(`/api/orders/${orderId}`, {
headers: { authorization: `Bearer ${userInfo.token}` },
});
dispatch({ type: 'FETCH_SUCCESS', payload: data });
} catch (err) {
dispatch({ type: 'FETCH_FAIL', payload: getError(err) });
}
};
if (!userInfo) {
return navigate('/login');
}
if (!order._id || (order._id && order._id !== orderId)) {
fetchOrder();
}
}, [order, userInfo, orderId, navigate]);
return loading ? ( // Deleted
<LoadingBox></LoadingBox> // Deleted until ") :"
) : error ? (
<MessageBox variant="danger">{error}</MessageBox>
) : (
<div>
<Helmet>
<title>Order {orderId}</title>
</Helmet>
<h1 className="my-3">Order {orderId}</h1>
<Row>
<Col md={8}>
<Card className="mb-3">
<Card.Body>
<Card.Title>Shipping</Card.Title>
<Card.Text>
<strong>Name:</strong> {order.shippingAddress.fullName} <br />
<strong>Address: </strong> {order.shippingAddress.address},
{order.shippingAddress.city}, {order.shippingAddress.postalCode}
,{order.shippingAddress.country}
</Card.Text>
{order.isDelivered ? (
<MessageBox variant="success">
Delivered at {order.deliveredAt}
</MessageBox>
) : (
<MessageBox variant="danger">Not Delivered</MessageBox>
)}
</Card.Body>
</Card>
<Card className="mb-3">
<Card.Body>
<Card.Title>Payment</Card.Title>
<Card.Text>
<strong>Method:</strong> {order.paymentMethod}
</Card.Text>
{order.isPaid ? (
<MessageBox variant="success">
Paid at {order.paidAt}
</MessageBox>
) : (
<MessageBox variant="danger">Not Paid</MessageBox>
)}
</Card.Body>
</Card>
<Card className="mb-3">
<Card.Body>
<Card.Title>Items</Card.Title>
<ListGroup variant="flush">
{order.orderItems.map((item) => (
<ListGroup.Item key={item._id}>
<Row className="align-items-center">
<Col md={6}>
<img
src={item.image}
alt={item.name}
className="img-fluid rounded img-thumbnail"
></img>{' '}
<Link to={`/product/${item.slug}`}>{item.name}</Link>
</Col>
<Col md={3}>
<span>{item.quantity}</span>
</Col>
<Col md={3}>${item.price}</Col>
</Row>
</ListGroup.Item>
))}
</ListGroup>
</Card.Body>
</Card>
</Col>
<Col md={4}>
<Card className="mb-3">
<Card.Body>
<Card.Title>Order Summary</Card.Title>
<ListGroup variant="flush">
<ListGroup.Item>
<Row>
<Col>Items</Col>
<Col>${order.itemsPrice.toFixed(2)}</Col>
</Row>
</ListGroup.Item>
<ListGroup.Item>
<Row>
<Col>Shipping</Col>
<Col>${order.shippingPrice.toFixed(2)}</Col>
</Row>
</ListGroup.Item>
<ListGroup.Item>
<Row>
<Col>Tax</Col>
<Col>${order.taxPrice.toFixed(2)}</Col>
</Row>
</ListGroup.Item>
<ListGroup.Item>
<Row>
<Col>
<strong> Order Total</strong>
</Col>
<Col>
<strong>${order.totalPrice.toFixed(2)}</strong>
</Col>
</Row>
</ListGroup.Item>
</ListGroup>
</Card.Body>
</Card>
</Col>
</Row>
</div>
);
}
this is my first post. I'm new to react and learn via a tutorial. I delete the unwanted parts with loading, I get a blank site and the error TypeError: Cannot read properties of undefined (reading 'fullName').
I have searched some solutions and tested things out but it will not work out. The order will be created but only the page will not display.
I really want to understand why this is happening and how to solve this.
function reducer(state, action) {
switch (action.type) {
case 'FETCH_REQUEST': // Deleted
return { ...state, loading: true, error: '' }; // Deleted
case 'FETCH_SUCCESS':
return { ...state, loading: false, order: action.payload, error: '' };
case 'FETCH_FAIL':
return { ...state, loading: false, error: action.payload };
default:
return state;
}
}
export default function OrderScreen() {
const { state } = useContext(Store);
const { userInfo } = state;
const params = useParams();
const { id: orderId } = params;
const navigate = useNavigate();
const [{ loading , error, order }, dispatch] = useReducer(reducer, { // Deleted "loading"
loading: true, // Deleted "loading: true"
order: {},
error: '',
});
useEffect(() => {
const fetchOrder = async () => {
try {
dispatch({ type: 'FETCH_REQUEST' }); // Deleted
const { data } = await axios.get(`/api/orders/${orderId}`, {
headers: { authorization: `Bearer ${userInfo.token}` },
});
dispatch({ type: 'FETCH_SUCCESS', payload: data });
} catch (err) {
dispatch({ type: 'FETCH_FAIL', payload: getError(err) });
}
};
if (!userInfo) {
return navigate('/login');
}
if (!order._id || (order._id && order._id !== orderId)) {
fetchOrder();
}
}, [order, userInfo, orderId, navigate]);
return loading ? ( // Deleted
<LoadingBox></LoadingBox> // Deleted until ") :"
) : error ? (
<MessageBox variant="danger">{error}</MessageBox>
) : (
<div>
<Helmet>
<title>Order {orderId}</title>
</Helmet>
<h1 className="my-3">Order {orderId}</h1>
<Row>
<Col md={8}>
<Card className="mb-3">
<Card.Body>
<Card.Title>Shipping</Card.Title>
<Card.Text>
<strong>Name:</strong> {order.shippingAddress.fullName} <br />
<strong>Address: </strong> {order.shippingAddress.address},
{order.shippingAddress.city}, {order.shippingAddress.postalCode}
,{order.shippingAddress.country}
</Card.Text>
{order.isDelivered ? (
<MessageBox variant="success">
Delivered at {order.deliveredAt}
</MessageBox>
) : (
<MessageBox variant="danger">Not Delivered</MessageBox>
)}
</Card.Body>
</Card>
<Card className="mb-3">
<Card.Body>
<Card.Title>Payment</Card.Title>
<Card.Text>
<strong>Method:</strong> {order.paymentMethod}
</Card.Text>
{order.isPaid ? (
<MessageBox variant="success">
Paid at {order.paidAt}
</MessageBox>
) : (
<MessageBox variant="danger">Not Paid</MessageBox>
)}
</Card.Body>
</Card>
<Card className="mb-3">
<Card.Body>
<Card.Title>Items</Card.Title>
<ListGroup variant="flush">
{order.orderItems.map((item) => (
<ListGroup.Item key={item._id}>
<Row className="align-items-center">
<Col md={6}>
<img
src={item.image}
alt={item.name}
className="img-fluid rounded img-thumbnail"
></img>{' '}
<Link to={`/product/${item.slug}`}>{item.name}</Link>
</Col>
<Col md={3}>
<span>{item.quantity}</span>
</Col>
<Col md={3}>${item.price}</Col>
</Row>
</ListGroup.Item>
))}
</ListGroup>
</Card.Body>
</Card>
</Col>
<Col md={4}>
<Card className="mb-3">
<Card.Body>
<Card.Title>Order Summary</Card.Title>
<ListGroup variant="flush">
<ListGroup.Item>
<Row>
<Col>Items</Col>
<Col>${order.itemsPrice.toFixed(2)}</Col>
</Row>
</ListGroup.Item>
<ListGroup.Item>
<Row>
<Col>Shipping</Col>
<Col>${order.shippingPrice.toFixed(2)}</Col>
</Row>
</ListGroup.Item>
<ListGroup.Item>
<Row>
<Col>Tax</Col>
<Col>${order.taxPrice.toFixed(2)}</Col>
</Row>
</ListGroup.Item>
<ListGroup.Item>
<Row>
<Col>
<strong> Order Total</strong>
</Col>
<Col>
<strong>${order.totalPrice.toFixed(2)}</strong>
</Col>
</Row>
</ListGroup.Item>
</ListGroup>
</Card.Body>
</Card>
</Col>
</Row>
</div>
);
}
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
当屏幕呈现时,使用效果代码块。在使用效果中,您正在获取异步函数的顺序数据。因此,加载数据需要一些时间。这就是为什么负载在那里。没有它,您的屏幕尝试渲染
order.shippingAddress.fullname
的值,但尚未定义。您有2个可以解决的选择:The useEffect block of code is called when the screen is rendered. In useEffect you are fetching order data which is asynchronous function. So it takes some time to load that data. That's why the loading was there. Without it your screen tries to render value of
order.shippingAddress.fullName
and that's not defined yet. You have 2 options to fix it:一旦页面加载,您就会从API获取数据,但是在获取值之前调用这些数据总是会出现错误。您应该以条件调用您的值:
{order&amp;&amp;订单。 order.shippingaddress.fullname? order.shippingAddress.fullname:“”}
。这给出了默认的空字符串值,直到获取数据为止。You're fetching your data from an API once the page loads but calling the values before they have been fetched is always going to give errors. You should conditionally call your values as such:
{order && order.shippingAddress && order.shippingAddress.fullName? order.shippingAddress.fullName : ""}
. This gives a default empty string values till your data is fetched.