渲染时子组件的状态不会改变

时间:2017-10-19 12:22:58

标签: reactjs github-api

我是ReactJs的新手所以请耐心等待。我正在尝试从this课程中构建一个名为Git-Hub profile viewer的项目。这是我的父组件代码:

import Profile from './github/Profile.jsx';


class App extends Component {
  constructor(props){
    super(props);
    this.state = {
      username: 'xxxx',
      userData: [],
      userRepos: [],
      perPage: 5
    }
  }
  // get user data from github
  getUserData(){
    $.ajax({
      url: 'https://api.github.com/users/' +this.state.username+'?client_id='+this.props.clientId+'&client_secret='+this.props.clientSecret,
      dataType:'json',
      cache:false,
      success: function(data){
        this.setState({userData:data});
        console.log(data);
      }.bind(this),
      error: function(xhr, status, err){
        this.setState({userData: null});
        alert(err);
      }.bind(this)
    });
  }
  componentDidMount(){
    this.getUserData();
  }
    render(){
      return (
        <div>
        <Profile userData = {this.state.userData} />
        </div>
      )

  }

}

App.propTypes = {
  clientId: React.PropTypes.string,
  clientSecret: React.PropTypes.string
};
App.defaultProps = {
  clientId: 'some_genuine_client_Id',
  clientSecret:'some_really_client_secret'

}
export default App;

这是我孩子的组成部分:

class Profile extends Component {


    render() {
      return (
        <div className="panel panel-default">
            <div className="panel-heading">
            <h3 className="panel-title">{this.props.userData.name}</h3>
          </div>
          <div className="panel-body">

          </div>
        </div>
      )

  }
}

export default Profile;

问题是子组件中的props在呈现页面时不会更新其状态,尽管数据检索是从Git-Hub成功完成的,如控制台日志中所示。我做错了什么,有人可以帮忙吗?

2 个答案:

答案 0 :(得分:0)

首先,您应该确保以正确的方式访问userData,正如@mersocarlin所提到的那样。这很可能是导致问题的原因。

理论上,你这样做的方式应该有效。但是我为你编写了一份工作jsfiddle作为例子。我无法进行Ajax调用,因此使用setTimeout事件模拟它超过5秒。

另一种方法是将getUserData函数传递给子组件(Profile)并让它自己处理调用。这是jsfiddle,以及下面的代码:

class Profile extends React.Component {

  constructor(props) {
    super(props);
    this.state = {
      userData: {}
    };
  }

    componentDidMount() {
      const userData = this.props.getUserData();
      console.log(userData);
      this.setState({ userData: userData });
    }

    render() {
      return (
        <div className="panel panel-default">
            <div className="panel-heading">
            <h3 className="panel-title">Hello, {this.state.userData.name || 'World'}</h3>
          </div>
          <div className="panel-body">

          </div>
        </div>
      )

  }
}

class App extends React.Component {
  getUserData(){
    return {
      'name': 'Tom'
    }
  }

  render(){
    return (
      <Profile getUserData={this.getUserData} />
    )
  }
};

答案 1 :(得分:0)

首先,您应该在getUserData()而不是componentWillMount中调用componentDidMount来获取组件呈现之前的数据。然后在子组件中使用生命周期方法componentWillReceiveProps来检查子组件是否正在获取正确的道具并相应地更新状态。它会是这样的:

componentWillReceiveProps(nextProps) {
  if(this.props.userData !== nextProps.userData) {
    console.log('condition met');
    this.setState({
      userData: nextProps.userData
    });
  }
}

试试这个让我知道,我会进一步帮助你。