简体   繁体   English

ES6 类实例变量如何工作

[英]How does ES6 class instance variable work

I have the following code which is working as expected:我有以下代码按预期工作:

import React, { Component } from 'react';

let result = null;
class MyData extends Component {
  _getData = () => {
    fetch(url)
      .then(response => response.json())
      .then(data => {
        result = items.find(
          item => item.id === 'abcd'
        );
      });
  };

  componentDidMount() {
    this._getData();
  }

  render() {
    return result ? <span>hello</span> : null;
  }
}

When I try to move result as an instance variable of the class as follows, it always remains null in the render() method.当我尝试将result作为类的实例变量移动时,如下所示,它在render()方法中始终保持为 Though the assignment is working correctly post fetch:虽然任务在提取后正常工作:

import React, { Component } from 'react';

class MyData extends Component {
  result = null;
  _getData = () => {
    fetch(url)
      .then(response => response.json())
      .then(data => {
        this.result = items.find(
          item => item.id === 'abcd'
        );
      });
  };

  componentDidMount() {
    this._getData();
  }

  render() {
    return this.result ? <span>hello</span> : null;
  }
}

Can someone explain me what is the expected usage here.有人可以解释我这里的预期用途是什么。 And how things have changed from ES6 onwards.以及从 ES6 开始发生的变化。

Both examples just don't work, the reason is that componentDidMount lifecycle fires after render lifecycle .这两个示例都不起作用,原因是componentDidMount生命周期在render生命周期之后触发

Because you don't cause re-render (with setState ) in any phase, nothing will cause an additional render to read the updated value of result .因为您不会在任何阶段导致重新渲染(使用setState ),所以不会导致额外的渲染读取result的更新值。

在此处输入图片说明

Therefore, the next example will always render No Result因此,下一个示例将始终呈现No Result

import ReactDOM from 'react-dom';
import React, { Component } from 'react';

let result = null;

class App extends Component {
  thisResult = null;
  setResult = () => {
    result = 10;
    this.thisResult = 10;
  };

  componentDidMount() {
    this.setResult();
  }

  render = () => {
    return <div>{result || this.thisResult ? 'Result' : 'No Result'}</div>;
  };
}

ReactDOM.render(<App />, document.getElementById('root'));

编辑华丽的雪花-u4s6x

The reason you are seeing null is because the state is not being updated in the code example you posted.您看到 null 的原因是因为您发布的代码示例中未更新状态。 The component mounts and this.result is null.组件挂载并且this.result为空。 But when the _getData method is called and the response comes back, the component is not being rendered.但是当_getData方法被调用并且响应回来时,组件没有被渲染。

You should be storing this data in your state, as React relies on the state changes to know when it should re-render the component.您应该将这些数据存储在您的状态中,因为 React 依赖于状态更改来知道何时应该重新渲染组件。 Try something like this:尝试这样的事情:

import React, { Component } from 'react';

class MyData extends Component {
  state = {
    result: null
  }
  _getData = () => {
    fetch(url)
      .then(response => response.json())
      .then(data => {
        this.setState({
          result: items.find(
            item => item.id === 'abcd'
          )
        })
      });
  };

  componentDidMount() {
    this._getData();
  }

  render() {
    const { result } = this.state
    return result ? <span>hello</span> : null;
  }
}

You can learn more about rendering, state, and component lifecycles here: https://reactjs.org/docs/state-and-lifecycle.html#adding-local-state-to-a-class您可以在此处了解有关渲染、状态和组件生命周期的更多信息: https : //reactjs.org/docs/state-and-lifecycle.html#adding-local-state-to-a-class

Edit: If you want to experiment with the new react hooks api, you could convert your component to look like the folllowing:编辑:如果您想尝试使用新的 react hooks api,您可以将您的组件转换为如下所示:

import React, { useEffect, useState } from 'react';

const MyData = ({ ...props }) => {
  const [result, setResult] = useState(null);

  const getData = () => {
    fetch(url)
      .then(response => response.json())
      .then(data => {
        const result = items.find(item => item.id === 'abcd');

        setResult(result);
      });
  };

  useEffect(() => {
    getData();
  }, []);

  return result ? <span>hello</span> : null;
}

I think the main thing you're missing is state.我认为您缺少的主要内容是状态。 Keep in mind that these Components you are extending are React Component classes which have a very specific life cycle.请记住,您正在扩展的这些组件是具有非常特定生命周期的 React 组件类。 Look into component life cycle for more info.查看组件生命周期以获取更多信息。 This will work as expected with the following refactor:这将通过以下重构按预期工作:

import React, { Component } from 'react';

class MyData extends Component {
    constructor() {
        super();
        this.state = {result:  null};
    }

    _getData = () => {
        fetch(url)
        .then(response => response.json())
        .then(data => {
            let resp = data.items.find(
                item => item.id === 'abcd'
            );

            this.setState({ result: resp });
        });
    };

    componentDidMount() {
        this._getData();
    }

    render() {
       return this.state.result ? <span>hello</span> : null;
    }
 }

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

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