繁体   English   中英

除非刷新页面,否则 React.js this.props 未定义

[英]React.js this.props undefined unless page is refreshed

所以,我有以下问题,我试图显示用户在用户个人资料中发表的所有帖子。 如果我从登录和 go 开始到配置文件,它会给我一个 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>

使用用户组件:

 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>

这是刷新时的控制台: 在此处输入图像描述

你能看出错误在哪里吗?

任何帮助将不胜感激:)

这可以通过向 HOC 添加 loading state 来解决,这样您就不会在获取数据之前渲染包装的组件。

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} />;
};

这是因为在useEffect中,axios是一个异步调用,

const withUser = (Component, options = { renderNull: true }) => props => {
  ...
  useEffect(() => {
    axios(`http://localhost:7001/api/users/${userId}`)
      .then(response => {
      
      setUserData(response.data)
    })
  }, [userId])

快速可靠的解决方案是在配置文件组件上添加默认道具

Profile.defaultProps = {
  user: [],
}

并检查必要

  getShares = () => {
    if(props.user.length === 0) return

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM