使用onClick调用父函数后,React状态未定义

时间:2018-03-20 23:09:47

标签: components

在子组件中,每当我单击其中一个映射的Span元素时,onClick就会触发父组件中的switchLaunch函数,并触发我现在用于测试目的的调试器。但是,我设置的所有状态现在都是未定义的。因此,当我调用 this.state.allPastLaunches 时,它现在未定义但如果我调用 this.allPastLaunches ,则数据就在那里。我对我出错的地方感到困惑

父组件(App)

class App extends Component {
  //api call for latest space launch
  constructor(props) {
    super(props);
    this.state = {
      selectedLaunch: "",
      launchData: "",
      videoURL: null,
      allPastLaunches: [],
      showVideo: false
    };
  }

  componentWillMount() {
    this.getLaunchData()
  }

  switchLaunch(launch) {
    debugger
    // ALL MY STATES ARE EMPTY HERE WHEN I TRY TO LOG THEM AFTER THE FUNCTION 
    IS TRIGGERED BY THE CHILD'S ONCLICK
  }


  getLaunchData() {
    // getting latest launch
    fetch('https://api.spalta.launch/launch')
      .then(response => {
        return response.json();
      })
      .then(json => {
        this.setState({ 
          launchData: json,
          videoURL: json.links["video_link"],
          missionPatch: json.links["mission_patch"]
        });
      });

    //getting all previous launches
    fetch('https://api.spalta.launch/prevLaunches')
      .then(response => {
        return response.json();
      })
      .then(json => {
        this.setState({ 
          allPastLaunches: json,
        });
      });

  }
  render() {
    let dataReady = this.state.videoURL;

    if (this.state.launchData != null) {
      return (
        <div className="App">
          {this.state.allPastLaunches ? 
             <Header 
               key="header"
               missionPatch = {this.state.missionPatch}
               allPastLaunches = {this.state.allPastLaunches}
               switchLaunch = {this.switchLaunch}
             />
           :
              <div>Loading...</div>
           }

子组件(标头)

class Header extends Component {

  componentDidMount() {
  }


  render() {

    var launches = this.props.allPastLaunches;

    var imgClass = classNames({
      'img-container': true,
      'animated': true,
      'fadeInDownBig': true
    });

    const component = this;

    return (
      <div key = "container" className="header-container">
        <div key = "img-container">
            {launches.map((launch, index) => 
                <span key = {index} onClick= {() => { component.props.switchLaunch(index) }} > 
                    {launch["rocket"].rocket_id}
                </span>

            )}

1 个答案:

答案 0 :(得分:2)

您需要绑定您的方法,使其具有正确的上下文,您可以在此处阅读更多相关信息:https://www.andreasreiterer.at/web-development/bind-callback-function-react/

class App extends Component {
  //api call for latest space launch
  constructor(props) {
    super(props);
  // This line makes sure that "this" is the correct 
  // thing when this method is called via callback
  this.switchLaunch = this.switchLaunch.bind(this);
    this.state = {
      selectedLaunch: "",
      launchData: "",
      videoURL: null,
      allPastLaunches: [],
      showVideo: false
    };
  }

  componentWillMount() {
    this.getLaunchData()
  }

  switchLaunch(launch) {
    debugger
    // ALL MY STATES ARE EMPTY HERE WHEN I TRY TO LOG THEM AFTER THE FUNCTION 
    IS TRIGGERED BY THE CHILD'S ONCLICK
  }
...

旧答案:

试试这个:

const component = this
return (
      <div key = "container" className="header-container">
        <div key = "img-container">
            {launches.map((launch, index) => 
                <span key = {index} onClick= {() => { component.props.switchLaunch(index) }} > 
                    {launch["rocket"].rocket_id}
                </span>

            )}

代码(launch, index) =>创建一个新函数,因此this是新函数的上下文(即隐藏原始this)。您需要将this保存为component并在内部函数中使用它。