【问题标题】:React update setState convert String to Array反应更新 setState 将字符串转换为数组
【发布时间】:2020-07-21 00:21:39
【问题描述】:

我正在构建一个 React CRUD 应用,我可以在其中添加新菜、显示菜列表、更新菜或删除菜。

我被困在更新菜肴的更新部分。每次编辑菜品标题时,我都可以对菜品标题进行编码以进行更新。但是,我无法编辑菜肴成分。我对成分进行了编码,以将字符串从 textarea 转换为数组。我需要这样做,因为我添加了一个过滤器功能,在该功能中输入一种成分,您会看到输入了该成分的可能菜肴。

我能够在“Add Dish”(<AddDish />) 组件中将字符串转换为数组。然后我在{this.showFood()} 中显示数组,其中我使用.join(", ") 将数组转换为字符串。

但是,我正在努力解决的部分是 updateDish() 函数。如果我编辑标题而不编辑成分,我可以显示所有内容。但是,如果我编辑成分并单击"Save" 按钮,则会收到错误消息“this.state.ingredients.join is not a function”。

我发现每次我尝试编辑成分时,它都会返回一个字符串。我尝试编辑代码以检查成分是否返回字符串,将字符串转换为数组,我可以看到它更新了我用作数据库的food-list.json,但我仍然收到此错误。请帮忙...

您可以在此演示 CodeSandBox 中查看所有内容:https://codesandbox.io/s/github/kikidesignnet/food-list/tree/master/

App.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>
    )
  }
}

【问题讨论】:

    标签: javascript arrays reactjs


    【解决方案1】:

    改为:

      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,这是字符串。

    【讨论】:

      猜你喜欢
      • 2022-11-02
      • 2020-01-02
      • 2021-05-12
      • 1970-01-01
      • 1970-01-01
      • 2016-07-24
      • 1970-01-01
      • 2017-11-27
      相关资源
      最近更新 更多