问题
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