简体   繁体   English

在componentWillMount方法中使用axios给我带来了一个奇怪的错误

[英]using axios in componentWillMount method got me an weired error

I wanted to use axios in my react code for getting data from the server. 我想在我的React代码中使用axios从服务器获取数据。 I put axios code in the componentWillMount of my react component like this. 我像这样将axios代码放在我的react组件的componentWillMount中。


componentWillMount()
    {   
        axios
        .get("https://jsonplaceholder.typicode.com/Posts")
        .then(function(response) {
            this.setState({Posts : response.data[0].title});
        })
        .catch(function(error) {
            console.log(error);
        });
    }

but above code thrown me an error like this 但是上面的代码抛出了这样的错误


TypeError: "this is undefined"
    componentWillMount Redux

but when I did slightly change in the code like the code below everything were going right. 但是当我在代码中做了些微更改时,例如下面的代码,一切都正确了。


componentWillMount()
    {   
        axios
        .get("https://jsonplaceholder.typicode.com/Posts")
        .then(response= > {
            this.setState({Posts : response.data[0].title});
        })
        .catch(error => {
            console.log(error);
        });
    }

Another thing that I want to say is the "this" object is active in the componentWillMount 我想说的另一件事是componentWillMount中的“ this”对象处于活动状态

is there anyone tell me the difference between two code above? 有没有人告诉我上面两个代码之间的区别?

MDN says: MDN说:

An arrow function [...] is an alternative to a regular function expression, although without its own bindings to the ´´this´´. 箭头函数是正则函数表达式的替代方法,尽管没有自己绑定到“ this”的地方。

If you use a regular function, this refers to the function itself (which is undefined ). 如果使用常规函数, this指的是函数本身( undefined )。 When using an arrow function, this remains untouched. 使用箭头功能时, this功能保持不变。

If you use the function(response) { ... } syntax, this is not inherited and will be undefined . 如果您使用function(response) { ... }语法,则this语法不会被继承,并且将是undefined You need to explicitly bind this to your React component so that it knows how to find this.setState : 你需要明确绑定this使得它知道如何找到你的阵营组件this.setState

componentWillMount()
{   
    axios
    .get("https://jsonplaceholder.typicode.com/Posts")
    .then(function(response) {
        this.setState({Posts : response.data[0].title});
    }.bind(this))  // <-- notice the .bind(this)
    .catch(function(error) {
        console.log(error);
    });
}

With the response => { ... } syntax the this context is inherited so this binding is not necessary. 使用response => { ... }语法,将继承this上下文因此不需要此绑定。

You need to use an arrow function to use this 您需要使用箭头功能才能使用this功能

You cannot use setState to access this when you use a function() declaration. 使用function()声明时,不能使用setState来访问this this will return undefined, as its scope doesn't point to the object that you created. this将返回未定义,因为其范围未指向您创建的对象。 So, instead, you should use the code below, 因此,您应该使用下面的代码,

Working code: 工作代码:

componentDidMount()
    {   
        axios
        .get("https://jsonplaceholder.typicode.com/Posts")
        .then(() => {
            this.setState({Posts : response.data[0].title}); // `this` object points to your object here because of the arrow function.
        })
        .catch(() => { // Same case here
            console.log(error);
        });
    }

Also, Junius is right about componentDidMount. 同样,Junius对componentDidMount也是正确的。

The best place to make calls to fetch data is within componentDidMount(). 调用获取数据的最佳位置是componentDidMount()。 componentDidMount() is only called once, on the client, compared to componentWillMount() which is called twice, once to the server and once on the client. 与componentWillMount()两次调用,一次服务器调用和一次客户端调用相比,componentDidMount()在客户端仅被调用一次。 More Info 更多信息

bind your function or use arrow function 绑定功能或使用箭头功能

componentWillMount = () => {

  axios("https://jsonplaceholder.typicode.com/Posts")
    .then((response) => {
      this.setState({ Posts: response.data[0].title });
    })
    .catch(function (error) {
      console.log(error);
    });
}

Edit 编辑

please use componentDidMount instead of componentWillMount 请使用componentDidMount而不是componentWillMount

componentDidMount = () => {}

or save the value of this in a variable. 或将此值保存在变量中。

componentDidMount = () => {

  const that = this;

  axios("https://jsonplaceholder.typicode.com/Posts")
    .then(function (response) {
      that.setState({ Posts: response.data[0].title });
    })
    .catch(function (error) {
      console.log(error);
    });
}

DEMO 演示

 <script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.6.0/umd/react.production.min.js"></script> <script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.6.0/umd/react-dom.production.min.js"></script> <script src="https://cdnjs.cloudflare.com/ajax/libs/babel-standalone/6.21.1/babel.min.js"></script> <script src="https://unpkg.com/axios/dist/axios.min.js"></script> <div id="root"></div> <script type="text/babel"> class App extends React.Component { constructor() { super(); this.state = { name: 'React', Posts: '', }; } componentDidMount = () => { const that = this; axios("https://jsonplaceholder.typicode.com/Posts") .then(function (response) { that.setState({ Posts: response.data[0].title }); }) .catch(function (error) { console.log(error); }); } render() { return ( <div> <p>Post title</p> <p>{this.state.Posts}</p> </div> ); } } ReactDOM.render(<App />, document.getElementById("root")); </script> 

this 这个

This is determined at runtime and depending on the code, it can be something different. 这是在运行时确定的,具体取决于代码,可能有所不同。

this is 这是

  • determined at runtime, when a function is envoked 在运行时确定何时调用函数
  • determined by how a function is invoked, not where the function is defined 由函数的调用方式决定,而不是由函数定义的地方决定
  • a reference to an object. 对对象的引用。
  • will always be an object 将永远是一个对象
  • global (this) not available in strict mode 全局(此)在严格模式下不可用

Example 1: this = window 示例1: this = window

 var name = 'Global'; var callName1 = function() { var name = 'Peter'; console.log('--- From callName1 ----'); console.log(this.name); //console.log(this); callName2(); } var callName2 = function() { var name = 'Jane'; console.log('--- From callName2 ----'); console.log(this.name); //console.log(this); } callName1(); var execute = function(fn) { var name = 'Mary'; console.log('--- From execute ----'); console.log(this.name); //console.log(this); } execute(callName2); 

Example 2: not available in strict mode 示例2:在严格模式下不可用

 'use strict'; var name = 'Global'; var callName1 = function() { var name = 'Peter'; console.log('--- From callName1 ----'); console.log(this.name); console.log(this); } callName1(); 

Example 3: examining this with method invocation 实施例3:用方法调用检查

 var name = 'global'; var obj = { name: 'James Obj1', func: function() { console.log('--- From func ----'); console.log(this.name); console.log(this); // this reference obj1 } } obj.func() var obj2 = { name: 'Jame Obj2', func: obj.func // this reference obj2, but the function is defined in obj1 } obj2.func() var obj3 = { name: 'Kane Obj3', obj4: { name: 'Mary Obj4', func: function () { console.log('--- From obj4 ----'); console.log(this.name); console.log(this); // this reference obj4 } } } obj3.obj4.func() 

With () => {} function this - is lexically bound. 使用() => {}函数, -在词法上受约束。 It means that it uses this from the code that contains the arrow function. 这意味着,它使用this从包含箭头函数的代码。

Just a minor update, From the react docs , componentWillMount() is considered to be unsafe for async rendering. 只是一个小小的更新,从react docscomponentWillMount()被认为对于异步渲染是不安全的。 If you do choose to continue to use it, you should use UNSAFE_componentWillMount() or you can just use componentDidMount() which is only called once. 如果确实选择继续使用它,则应使用UNSAFE_componentWillMount() ,也可以只使用componentDidMount() ,后者仅被调用一次。 The “UNSAFE” prefix refers not to security but instead conveys that code using these lifecycles will be more likely to have bugs in future versions of React, especially once async rendering is enabled. “ UNSAFE”前缀不是指安全性,而是表示使用这些生命周期的代码在React的未来版本中更有可能出现错误,尤其是在启用异步渲染后。

     UNSAFE_componentWillMount()
       {   
       axios.get("https://jsonplaceholder.typicode.com/Posts")
        .then(() => {
            this.setState({Posts : response.data[0].title});
        })
        .catch(() => { 
            console.log(error);
        });
       }  

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

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