Why is unmounting a child component displays an error

本秂侑毒 提交于 2019-12-11 16:08:19

问题


Parent Component:

  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

Child Component:

  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

The ShowWeatherButton(parent) component calls the ShowWeatherDetails(child) if the anchor link with class btn btn-icon btn-pinterest is called in the parent component. When I click the X icon in the child component, I want to unmount the ShowWeatherDetails component so it can be called again if I click the anchor link.

I tried the method above but I get this error:

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

Please help me resolve my issue

UPDATE: So I figured out the error because I didn't bind. However now it unmounts first time but the next time I click the button the child component doesn't load anymore. I am guessing it's because the state in the child didn't change.

How can I best do this logic.


回答1:


You forgot to bind this.closeChild.bind(this). Be sure to add this to your constructor:

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

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



回答2:


You can take advantage of ES6 arrow function by which you don't have to bind this explicitly.

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


来源:https://stackoverflow.com/questions/56874753/why-is-unmounting-a-child-component-displays-an-error

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!