我正在构建一个简单的食谱框,人们可以在其中添加食谱,它将保存到localStorage
。目前我有一个弹出窗口,可以在其中添加食谱,然后保存。您可以看到以下界面:
当我按下“关闭我”按钮时,我可以根据需要在主屏幕和弹出窗口之间切换。但是,如果我首先单击“添加配方”,则“关闭我”按钮将不再起作用并触发错误:(父组件中的this.setState)未定义。
非常感谢有关为何发生这种情况以及如何解决问题的任何信息。
以下是Codepen的链接:https://codepen.io/lieberscott/pen/JpPbZd?editors=0110
这是我的代码。与此行为交互的两个类是Box类和Addpopup类:
class Mainbutton extends React.Component {
constructor(props) {
super(props);
}
render() {
return (
<button onClick={this.props.toggleClose}>
Add recipe
</button>
);
}
}
class Recipes extends React.Component {
constructor(props) {
super(props);
this.state = {
isExpanded: false,
height: 0
}
}
handleToggle(e) {
e.preventDefault();
this.setState({
isExpanded: !this.state.isExpanded,
height: this.refs.inner.clientHeight
});
}
render() {
const currentHeight = this.state.isExpanded ? this.state.height : 0;
const ingredients = this.props.item.ingredients.map(ingredient => {
return (
<div>
{ingredient}
</div>
);
});
return (
<div className="panel" onClick={(e) => this.handleToggle(e)}>
<h4>{this.props.item.name}</h4>
<div
className="panel-collapse"
style={{height: currentHeight + "px"}}>
<div ref="inner">
{ingredients}
</div>
</div>
</div>
);
}
}
class Box extends React.Component {
constructor(props) {
super(props);
this.state = {
popup: true,
items: [
{
name: "Tofu tacos",
ingredients: [
"Tofu",
"Chili powder",
"Onion",
"Cumin",
"Oregano",
"Paprika",
"Salt",
"Pepper",
"Taco shells",
"Lettuce",
"Mozarella cheese"
] // end of ingredients array
}, // end of first item
{
name: "Spaghetti",
ingredients: [
"pasta",
"sauce"
]
} // end of second item
] // end of items array
} // end of this.state
this.togglePopup = this.togglePopup.bind(this);
this.addRecipe = this.addRecipe.bind(this);
} // end of constructor
togglePopup() {
console.log("close fired");
this.setState({
popup: !this.state.popup
});
}
addRecipe(food) {
console.log(food);
let foods = this.state.items;
this.setState = ({
items: foods.push(food)
});
console.log(this.state.items);
}
render() {
const allitems = this.state.items.map(oneitem => (
<Recipes item={oneitem} />
));
return (
<div>
{allitems}
{this.state.popup ? <Addpopup addRecipe={this.addRecipe} closeMe={this.togglePopup} /> : null}
<Mainbutton toggleClose={this.togglePopup}/>
</div>
);
}
}
class Addpopup extends React.Component {
constructor(props) {
super(props);
this.state = {
food: ""
};
this.changeFood = this.changeFood.bind(this);
this.addRec = this.addRec.bind(this);
}
changeFood(e) {
this.setState({
food: e.target.value
});
console.log(this.state.food);
}
addRec() {
let food = this.state.food;
this.props.addRecipe(food);
}
render() {
return (
<div className="popup">
<div className="popup-inner">
<input type="text" placeholder="Food" onChange={this.changeFood}></input><br/>
<input type="text" placeholder="Ingredients (seperated by commas)"></input><br/>
<button onClick={this.addRec}>Add recipe</button>
<button onClick={this.props.closeMe}>close me</button>
</div>
</div>
);
}
}
class Headline extends React.Component {
render() {
return (
<div>
<h1>Recipes</h1>
<br/>
</div>
);
}
}
class App extends React.Component {
render() {
return (
<div>
<Headline />
<Box />
</div>
);
}
}
const app = document.getElementById("app");
ReactDOM.render(<App />, app);
答案 0 :(得分:3)
当您点击Add Recipe
按钮时,您将重新分配我认为是拼写错误的this.setState
。在addRecipe
功能中,您有以下行
this.setState = ({
items: foods.push(food)
});
将此行更改为
this.setState({
// Array.push return length of array. So use spread operator like this
items: [...foods, food]
});