为什么卸载 child 组件会显示错误
Why is unmounting a child component displays an error
Parent 分量:
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 分量:
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
ShowWeatherButton(parent) 组件调用 ShowWeatherDetails(child) 如果在 parent 组件。
当我单击 child 组件中的 X
图标时,我想卸载 ShowWeatherDetails 组件,以便在单击锚 link.
时可以再次调用它
我尝试了上面的方法但是我得到了这个错误:
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 | }
请帮我解决问题
更新:所以我发现了错误,因为我没有绑定。但是现在它第一次卸载但是下次我单击按钮时 child 组件不再加载。我猜这是因为 child 中的状态没有改变。
我怎样才能最好地执行此逻辑。
您忘记绑定 this.closeChild.bind(this)
。请务必将此添加到您的构造函数中:
constructor(props) {
super(props)
this.state = {
showChild: true
}
// Add this line
this.closeChild = this.closeChild.bind(this)
}
您可以利用 ES6 箭头函数,通过它您不必显式绑定 this
。
closeChild = () => {
this.setState({
showChild: false
});
};
Parent 分量:
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 分量:
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
ShowWeatherButton(parent) 组件调用 ShowWeatherDetails(child) 如果在 parent 组件。
当我单击 child 组件中的 X
图标时,我想卸载 ShowWeatherDetails 组件,以便在单击锚 link.
我尝试了上面的方法但是我得到了这个错误:
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 | }
请帮我解决问题
更新:所以我发现了错误,因为我没有绑定。但是现在它第一次卸载但是下次我单击按钮时 child 组件不再加载。我猜这是因为 child 中的状态没有改变。
我怎样才能最好地执行此逻辑。
您忘记绑定 this.closeChild.bind(this)
。请务必将此添加到您的构造函数中:
constructor(props) {
super(props)
this.state = {
showChild: true
}
// Add this line
this.closeChild = this.closeChild.bind(this)
}
您可以利用 ES6 箭头函数,通过它您不必显式绑定 this
。
closeChild = () => {
this.setState({
showChild: false
});
};