API尚未响应时如何使用无状态组件的反应?

时间:2019-08-10 12:04:17

标签: reactjs axios

我正在Laravel中使用React,并且正在尝试构建一个简单的FriendsList组件以显示来自API的数据。 问题在于,Parent(配置文件)组件在获取数据之前已完成加载,因此FriendsList组件返回错误,因为道具第一次为空。务必要指出的是,无论API响应如何-父(配置文件)组件运行良好,第一次将其加载为空-然后添加数据。

Api通话

 export const getProfile = () => {
 return axios
     .get('api/profile', {
        headers: { Authorization: `Bearer ${localStorage.usertoken}` }
     })
    .then(response => {
        // console.log(response.data)
        return response.data
    })
    .catch(err => {
        console.log(err)
    })
 }

父组件

        import React, { Component } from 'react'
        import { getProfile } from './UserFunctions'
        import FriendsList from './FriendsList';

        class Profile extends Component {
            constructor() {
                super()
                this.state = {
                    name: '',
                    hobbies: '',
                    user_bday: '',
                    members: [],
                    error: '',

                }

            }

            componentDidMount() {

                getProfile().then(res => {
                    //   console.log(JSON.parse(res))
                    this.setState({
                        name: res.user.name,
                        hobbies: res.user.hobbies,
                        user_bday: res.user.user_birthday,
                        related_friends: res.user.related_friends,
                        members: res.user.members,

                    })

                })
            }


            render() {

                return (
                    <div className="container">
                        <div className="jumbotron mt-5">
                            <div className="col-sm-4 mx-auto">
                                <h1 className="text-center">PROFILE</h1>
                            </div>
                            <table className="table col-md-4 mx-auto">
                                <tbody>
                                    <tr>
                                        <td>Name</td>
                                        <td>{this.state.name}</td>
                                        <td>{this.state.hobbies}</td>
                                        <td>{this.state.user_bday}</td>

                                    </tr>
                                </tbody>
                            </table>
                            <FriendsList members={this.state.members}> 
       </FriendsList>
                        </div>
                    </div>
                )
            }
        }

        export default Profile

    import React from 'react';
     class FriendsList extends React.Component {

      render() {
        console.log(this.props)
        const { members } = this.props;
        const listmembers = members.map((item, index) => (
          <li key={item + index}>{item.name}</li>
        ));
        return (
          <div>
            {listmembers}
          </div>
        );
      }
    }
    export default FriendsList

4 个答案:

答案 0 :(得分:1)

有两种方法可以解决这个问题。

第一种方法:

class Profile extends Component {
  render() {
    // check if your `state` has all the necessary values
    // before rendering your JSX

    const { name, hobbies, user_bday, members } = this.state
    const shouldRender = name !== '' && 
      hobbies !== '' &&
      user_bday !== '' &&
      Array.isArray(members) && members.length > 0

    if (!shouldRender) {
      return null;
    }
    return (...)
  }
}

这样,您只有在JSX拥有所需的一切时才渲染state


第二种方法:

class Profile extends Component {
  constructor() {
    // ...
    this.setState = {
      members: []
    }
  }
}

members设置为一个空数组,而不是一个空字符串,这样,当您将其作为prop传递给FriendList组件时,调用this.props.friends.map实际上是正确的,但由于数组最初为空,因此不会呈现任何内容。


此外,看起来您从未在API调用完成后更新members

componentDidMount() {
  getProfile().then(res => {
    this.setState({
      name: res.user.name,
      hobbies: res.user.hobbies,
      user_bday: res.user.user_birthday,
      related_friends: res.user.related_friends,
    })
  })
}

因此,您的members实际上是一个空字符串。确保您使用正确的类型(在这种情况下应为数组)更新状态。

答案 1 :(得分:0)

如果我正确理解了这个问题,那么您在谈论null props ...另外,注释中的Kellen是正确的...您应该将成员设置为空数组,而我看不到您正在更新您setState ...

中的成员的状态

尝试:

render() {
    const friendsList =
        this.props.firends &&
        this.props.friends.map(function(item, index) {
            <li key={index}>{item.name}</li>;
        });

    return (
        <div>
            <ul>{friendsList}</ul>
        </div>
    );
}

答案 2 :(得分:0)

如果我理解了您的问题,我想您需要看一下https://www.npmjs.com/package/prop-types,我认为您的问题在于默认的props值,并且该库可以帮助您实现所需的行为。

答案 3 :(得分:0)

这里的另一种方法是使用loading状态,在此状态下,您将显示加载指示器等。

class Profile extends Component {
  constructor() {
    super();
    this.state = {
      name: "",
      hobbies: "",
      user_bday: "",
      members: "",
      error: "",
      isMembers: false,
      loading: true // Add loading state
    };
  }

  componentDidMount() {
    getProfile().then(res => {
      //   console.log(JSON.parse(res))
      this.setState({
        name: res.user.name,
        hobbies: res.user.hobbies,
        user_bday: res.user.user_birthday,
        related_friends: res.user.related_friends,
        loading: false // Remove the loading state when data is fetched
      });
    });
  }

  render() {
    return this.state.loading ? (
      <p> Loading... </p>
    ) : (
      <div className="container">
        <div className="jumbotron mt-5">
          <div className="col-sm-4 mx-auto">
            <h1 className="text-center">PROFILE</h1>
          </div>
          <table className="table col-md-4 mx-auto">
            <tbody>
              <tr>
                <td>Name</td>
                <td>{this.state.name}</td>
                <td>{this.state.hobbies}</td>
                <td>{this.state.user_bday}</td>
              </tr>
            </tbody>
          </table>
          {/*<FriendsList friends={this.state.members}></FriendsList>*/}
        </div>
      </div>
    );
  }
}