无法读取未定义

时间:2017-08-09 18:20:14

标签: javascript reactjs webpack ecmascript-6 babel

import React,{Component} from 'react';
import ReactDOM from 'react-dom';
import axios from 'axios';
import videoDetails from './components/listvideos';

class YoutubeApp extends Component {
    constructor(props){
        super(props)

    this.state = {
          videos:[]
    };

    this.apiCall('surfing');
    
   
}
    apiCall(term){
        const params = {
            part: 'snippet',
            key:APP_KEY,
            q:term,
            type: 'video'
        };
    axios.get(APP_URL, { params: params})
        .then(function(response) {
           this.setState({
               videos:response
           })
        })
        .catch(function(error) {
        console.error(error);
      });
   }

    render(){
        
        return (
            <div>
            <videoDetails/>
            </div>
        )
    }


}


ReactDOM.render(
    <YoutubeApp/>,
    document.getElementById('app')
)
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/0.14.8/react.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/0.14.8/react-dom.min.js"></script>
<div id="app">
</div>

您好我正在尝试制作一个youtube克隆用于练习我是这个的初学者但我不明白为什么反应状态给我一个问题 我试图将状态设置为我的视频数组,所以我可以将它传递给其他组件我没有包括api键或url,但是这是错误的方式是非常可读的 {无法读取未定义属性'setState'}

4 个答案:

答案 0 :(得分:4)

您在Promise链中使用function(),这将更改this的范围。如果您正在使用ES6,我建议您使用箭头功能来维护类范围。例如:

你正在使用

axios.get(APP_URL, { params: params})
    .then(function(response) { // this resets the scope
       this.setState({
           videos:response
       })
    })

尝试使用箭头功能:

axios.get(APP_URL, { params: params})
    .then((response) => {
       this.setState({
           videos:response
       })
    })

答案 1 :(得分:0)

您可以将当前上下文this分配给变量,也可以使用ES5或ES6保持一致。

apiCall(term) {
  const params = {
    part: 'snippet',
    key: APP_KEY,
    q: term,
    type: 'video'
  };
  const _this = this;

  axios.get(APP_URL, { params: params})
   .then((response) => {
     _this.setState({
       videos: response
     });
   })
   .catch((error) => {
    console.error(error);
   });
}

答案 2 :(得分:0)

这是由于您的API调用中的范围。 this的值在您的保证链中的response回调中有所不同。有两种方法可以解决这个问题。

您可以在this方法的开头设置引用apiCall的变量。

apiCall(term){

    const that = this;

    const params = {
        part: 'snippet',
        key:APP_KEY,
        q:term,
        type: 'video'
    };

   axios.get(APP_URL, { params: params}).then(function(response) {
       that.setState({
           videos:response
       });
    }).catch(function(error) {
       console.error(error);
  });

}

或者您可以使用ES6箭头功能,它保持原始范围,如下所示:

axios.get(APP_URL, { params: params}).then(response => {
    this.setState({
         videos:response
    });
})

答案 3 :(得分:0)

您还可能需要在company_list = cron.rest_client.load(config, "companies", '') if not company_list: logging.info("Company list is empty") return "Ok" company_objs=[] for row in company_list: company_objs.append(company_repository.save(row,original_data_source, actual_data_source)) # put 500 at a time if len(company_objs) > 500: ndb.put_multi(company_objs) company_objs=[] # put any remainders if len(company_objs) > 0: ndb.put_multi(company_objs) 方法的this.apiCall = this.apiCall.bind(this)之前添加this.apiCall('surfing');。这会将constructor的范围绑定到反应组件的范围。

更多信息:https://facebook.github.io/react/docs/handling-events.html

此外,从apiCall中删除this.apiCall('surfing');并将其放入constructor函数中,不应将构造函数用于执行。