为什么卸载子组件会显示错误

时间:2019-07-03 16:46:14

标签: reactjs react-component unmount

父项:

  import React, {Component} from "react";

  import ShowWeatherDetails from "./ShowWeatherDetails"

  class ShowWeatherButtons extends Component {
    constructor(props) {
      super(props)
      this.state = {
        buttonCount: 0,
        displayDetail: false
      }
      this.createButtons = this.createButtons.bind(this)
    }

    ShowThisWeather = (event) => {
      event.preventDefault()
      this.setState({
        displayDetail: true
      })
      console.log("test")
    }

    createButtons = () => {
      let cResult = this.props.cityResult
      let crLen = this.props.cityResult.length
      console.log(cResult)
      var countIt = 0

      var result = [];
      for (let y = 0; y < crLen; y++) {
         var theButtonText
         theButtonText = cResult[y].components.country === "USA"
         ?
            (cResult[y].components._type === "state_district" ?
              this.props.textValue :
              (cResult[y].components._type === "state" ? this.props.textValue : cResult[y].components.city + ", " + cResult[y].components.state)
            )
            + ", " + cResult[y].components.country
         :
            cResult[y].components.city + ", " + cResult[y].components.country
         result.push(
            <a
              className="btn btn-icon btn-pinterest"
              href="#"
              data-lat={cResult[y].geometry.lat}
              data-lng={cResult[y].geometry.lng}
              onClick={this.ShowThisWeather}
              >
              <i
                className="fa fa-facebook fa fa-sun-o">
              </i>
              <span>
                {theButtonText} Weather
              </span>
            </a>
         )
      }

      return result
    }

    componentWillUnmount() {
      console.log("unmounted SWB")
    }

    componentDidMount() {
      console.log("mounted SWB")
    }

    render() {
      return (
        <div className="weatherResult hidO posRel">
          <div className="sResultCount">
            <h2>{this.props.countEntry} result{this.props.countEntry > 1 ? "(s)" : null} found</h2>
          </div>
          <div className="sResult autO">
            {this.createButtons()}
          </div>
          {this.state.displayDetail ? <ShowWeatherDetails /> : null}
        </div>
      )
    }
  }

  export default ShowWeatherButtons

子组件:

  import React, {Component} from "react";

  class ShowWeatherDetails extends Component {
    constructor(props) {
      super(props)
      this.state = {
        showChild: true
      }
    }

    GetWeatherDetail() {
      fetch("url")
        .then(function(response) {
          return response.json()
        })
        .then(function(myJson) {
          console.log(myJson)
        })
    }

    closeChild() {
      this.setState({
        showChild: false
      })
    }

    render() {
      return (
        this.state.showChild ?
        <div className={"show setH posAbs"}>
          <div className={"posRel"}>
          <span className="close-icon" onClick={this.closeChild}>
            <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 40 40" enableBackground="new 0 0 40 40">
              <line x1="15" y1="15" x2="25" y2="25" stroke="#fff" strokeWidth="2.5" strokeLinecap="round" strokeMiterlimit="10"></line>
              <line x1="25" y1="15" x2="15" y2="25" stroke="#fff" strokeWidth="2.5" strokeLinecap="round" strokeMiterlimit="10"></line>
              <circle className="circle" cx="20" cy="20" r="19" opacity="0" stroke="#000" strokeWidth="2.5" strokeLinecap="round" strokeMiterlimit="10" fill="none"></circle>
              <path d="M20 1c10.45 0 19 8.55 19 19s-8.55 19-19 19-19-8.55-19-19 8.55-19 19-19z" className="progress" stroke="#fff" strokeWidth="2.5" strokeLinecap="round" strokeMiterlimit="10" fill="none"></path>
            </svg>
          </span>
          </div>
          {console.log("HERE")}
        </div>
        :
        null
      )
    }
  }

  export default ShowWeatherDetails

如果在父组件中调用了类btn btn-icon btn-pinterest的锚链接,则ShowWeatherButton(父)组件将调用ShowWeatherDetails(子组件)。 当我单击子组件中的X图标时,我想卸载ShowWeatherDetails组件,以便在单击锚点链接时可以再次调用它。

我尝试了上述方法,但出现此错误:

  TypeError: Cannot read property 'setState' of undefined
  closeChild
  src/Components/ShowWeatherDetails.js:40
    37 | }
    38 | 
    39 | closeChild() {
  > 40 |   this.setState({
       | ^  41 |     showChild: false
    42 |   })
    43 | }

请帮助我解决问题

更新:所以我发现了错误,因为我没有绑定。但是现在它是第一次卸载,但是下次我单击该按钮时,子组件不再加载。我猜是因为孩子的状态没有改变。

我怎样才能最好地做到这一点。

2 个答案:

答案 0 :(得分:1)

您忘记绑定this.closeChild.bind(this)。确保将其添加到您的构造函数中:

 constructor(props) {
    super(props)
    this.state = {
      showChild: true
    }

    // Add this line
    this.closeChild = this.closeChild.bind(this)
 }

答案 1 :(得分:0)

您可以利用ES6箭头功能,无需显式绑定this

closeChild = () => {
    this.setState({
      showChild: false
    });
  };