ES6类实例变量如何工作

时间:2019-12-06 16:29:32

标签: javascript reactjs ecmascript-6 es6-class

我有以下代码可以正常工作:

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;
  }
}

当我尝试将result作为类的实例变量移动时,它在render()方法中始终保持 null 。尽管任务在提取后正常运行:

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;
  }
}

有人可以告诉我这里的预期用途是什么。以及从ES6开始的情况如何变化。

3 个答案:

答案 0 :(得分:4)

两个示例都不起作用,原因是componentDidMount个生命周期在render个生命周期之后触发

因为在任何阶段都不会引起重新渲染(使用setState),所以不会导致其他渲染来读取result的更新值。 / p>

enter image description here

因此,下一个示例将始终呈现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'));

Edit flamboyant-snowflake-u4s6x

答案 1 :(得分:1)

看到空值的原因是因为发布的代码示例中的状态未更新。组件已安装,this.result为空。但是,当调用_getData方法并返回响应时,则不会呈现该组件。

您应该将数据存储在您的状态中,因为React依赖状态更改来知道何时应重新呈现组件。尝试这样的事情:

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;
  }
}

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

编辑:如果您想尝试使用新的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;
}

答案 2 :(得分:0)

我认为您最缺少的是状态。请记住,您要扩展的这些组件是React Component类,它们具有非常特定的生命周期。查看组件生命周期以获取更多信息。通过以下重构,这将按预期工作:

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;
    }
 }