[英]React update setState convert String to Array
我正在構建一個 React CRUD 應用程序,我可以在其中添加新菜、顯示菜列表、更新菜或刪除菜。
我被困在更新菜餚的更新部分。 每次編輯菜品標題時,我都可以對菜品標題進行編碼以進行更新。 但是,我無法編輯菜餚成分。 我對成分進行了編碼,以將字符串從 textarea 轉換為數組。 我需要這樣做,因為我添加了一個過濾器 function,其中輸入了一種成分,您會看到輸入了該成分的可能菜餚。
我能夠在“Add Dish”( <AddDish />
)組件中將字符串轉換為數組。 然后我在{this.showFood()}
中顯示數組,在其中我使用.join(", ")
將數組轉換為字符串。
但是,我正在努力解決的部分是updateDish()
function。 如果我編輯標題而不編輯成分,我可以顯示所有內容。 但是,如果我編輯成分並單擊"Save"
按鈕,則會收到錯誤消息“this.state.ingredients.join 不是函數”。
我發現每次我嘗試編輯成分時,它都會返回一個字符串。 我嘗試編輯代碼以檢查成分是否返回字符串,將字符串轉換為數組,我可以看到它更新了我用作數據庫的food-list.json
但我仍然收到此錯誤。 請幫忙...
您可以在此演示 CodeSandBox 中查看所有內容: https://codesandbox.io/s/github/kikidesignnet/food-list/tree/master/
應用程序.js
import React, { Component } from "react";
import DishBox from "./components/DishBox/index";
import AddDish from "./components/AddDish/index";
import SearchBox from "./components/SearchBox/index";
import './App.css';
import fooddb from "../src/food-list.json";
import 'bootstrap/dist/css/bootstrap.min.css';
class App extends Component {
constructor(props) {
super(props);
this.state = {
list: fooddb,
filtered: fooddb,
searchInput : ""
}
}
searchChange = (filterText) => {
this.setState({
searchInput: filterText
});
}
addDish = (newDish) => {
console.log("newdish", newDish);
newDish.ingredients = newDish.ingredients.split(", ");
const dishsCopy = [...this.state.list];
dishsCopy.push(newDish);
this.setState({
list: dishsCopy,
filtered: dishsCopy
})
}
showFood = () =>{
let currentArr = [...this.state.filtered];
const filter = this.state.searchInput.toLowerCase();
if(filter !== "") {
currentArr = currentArr.filter((d) => {
let lc = d.ingredients.map((ing) => ing.toLowerCase());
return lc.includes(filter)
})
}
return currentArr.map((eachFood, index) => {
return(
<DishBox
key={index}
id={index}
dish={eachFood.food}
ingredients={eachFood.ingredients}
updateDish={this.updateDish}
clickToDelete={this.deleteDish.bind(index)}
/>
);
});
}
updateDish = (i, food, ingredients) => {
console.log("updatedIng", typeof ingredients);
const filteredCopy = [...this.state.filtered];
filteredCopy[i].food = food;
if(typeof ingredients === "string") {
filteredCopy[i].ingredients = ingredients.split(",");
} else {
filteredCopy[i].ingredients = ingredients;
}
this.setState({
list: filteredCopy,
filtered: filteredCopy
});
}
deleteDish = (dishIndex) => {
const dishsCopy = [...this.state.list];
dishsCopy.splice(dishIndex, 1);
this.setState({
list: dishsCopy,
filtered: dishsCopy
})
}
render() {
console.log("json db", this.state.filtered);
return (
<div className="App">
<header className="App-header">
<h1>Grand Food Tour</h1>
</header>
<div className="food-section">
<div className="container">
<SearchBox searchInput={this.state.searchInput} searchChange={this.searchChange}/>
<div className="food-list">
{this.showFood()}
</div>
<AddDish addDish={this.addDish} />
</div>
</div>
</div>
);
}
}
export default App;
DishBox.js
import React, { Component } from 'react';
export default class DishBox extends Component {
constructor(props) {
super(props);
this.state = {
food: this.props.dish,
ingredients: this.props.ingredients,
indexNum: this.props.id,
isEditing: false
}
this.handleUpdate = this.handleUpdate.bind(this);
this.pressEditBtn = this.pressEditBtn.bind(this);
this.cancel = this.cancel.bind(this);
}
onFoodChange = (event) => {
event.preventDefault();
console.log("foodchange", event.target.value);
this.setState({ food: event.target.value });
}
onIngChange = (event) => {
event.preventDefault();
console.log("ingchange", event.target.value);
this.setState({ ingredients: event.target.value});
}
pressEditBtn = () => {
this.setState(state => ({ isEditing: !state.isEditing }));
}
cancel = () => {
this.setState(state => ({ isEditing: !state.isEditing }));
}
handleUpdate = () => {
// event.preventDefault();
console.log("foodchange", this.state.food);
console.log("ingchange", typeof this.state.ingredients);
this.props.updateDish(this.state.indexNum, this.state.food, this.state.ingredients);
this.setState(state => ({ isEditing: !state.isEditing }));
}
render() {
const { isEditing, index } = this.state;
return (
<div className="dish-box">
<div className="left-flex">
<div className="food-title">
{isEditing ? (<input type="text" name="food" value={this.state.food} onChange={event => this.onFoodChange(event, index)} />) : (<h2>{this.props.dish}</h2>)}
</div>
{isEditing ? (<textarea name="ingredients" value={this.state.ingredients} onChange={event => this.onIngChange(event, index)} ></textarea>) : (<p>{this.state.ingredients.join(", ")}</p>)}
</div>
<div className="right-flex">
{isEditing ? (<button type="button" className="btn btn-success" onClick={this.handleUpdate} >Save</button>)
: (<button type="button" className="btn btn-success" onClick={this.pressEditBtn} >Edit</button>)}
{isEditing ? (<button type="button" className="btn btn-danger" onClick={this.cancel}>Cancel</button>)
: (<button type="button" className="btn btn-danger" onClick={this.props.clickToDelete}>Delete</button>)}
</div>
</div>
)
}
}
改成:
onIngChange = event => {
event.preventDefault();
console.log("ingchange", event.target.value);
this.setState({ ingredients: event.target.value.split(",") }); // convert string to array
};
原因是您將state
設置為event.target.value
這是字符串。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.