Как мне работать с массивом в реализации CRUD-приложения? - PullRequest
4 голосов
/ 27 февраля 2020

Я создаю приложение CRUD, в котором name, dob, year хранятся в виде элементов массива (элементов) в состоянии. Каждый отображаемый элемент из массива имеет кнопку update и delete . В настоящее время я застрял в функции редактирования, и я хочу:

  1. Установить значение по умолчанию для каждого поля ввода обновления для отображаемого значения
  2. Заменить существующее значение в массиве элементов на обновленное значение

Вот код, который у меня есть до сих пор

/* when 'edit' button is clicked */

<form onSubmit={this.handleUpdate}>
    <input 
        className=""
        name="name"
        value={/* this section */}
        placeholder= "Celebrant's Name" 
        ref={name => this.name = name}
        required/> 
    <input 
        className=""
        type="number" 
        name="day"
        min="1" 
        max="31"
        ref={day => this.day = day}
        placeholder= "day"/>
    <input 
        className=""
        name="dob"
        type="month"/>

    <button type="submit">update</button>
    <button onClick={this.handleEditCancel}>cancel</button>
</form>

/*displays each item in the items Array */

this.state.items.map((item, key) => ( 
    <li key={key}>
        <span> {item.name} </span>
        <span> {item.day} </span>
        <span> {item.dob} </span>
        <button 
            className="btn btn-light"
            onClick={this.handleEdit} >edit</button>
        <button 
            className="btn btn-danger" 
            onClick={() => this.handleDelete(key)}>delete</button>
    </li>
))}

/* edit functions */

handleEdit(){
    this.setState({ toggle: true });
}

handleUpdate(event){
    event.preventDefault();
    console.log(this.name.value);
}

/* state */ 
this.state = {
    name: '',
    day: '',
    dob: '',
    toggle: false,
    items : []
}

Как я могу это реализовать?

Ответы [ 4 ]

3 голосов
/ 09 марта 2020

Вы должны использовать ID для всех полей ввода. Используя эти идентификаторы, вы можете получить доступ к значению через getElementById.value и можете setState обновить переменную состояния. Обновите состояние с помощью handleEdit метода. Каждый элемент строки должен поддерживаться уникальным идентификатором. Это должно быть использовано для редактирования выбранных данных.

2 голосов
/ 11 марта 2020

Некоторые вещи, которые мне помогли при создании форм:

  • Сохранение идентификатора элемента, который я редактирую
  • , используйте onChange и Атрибуты входного тега value для двухстороннего связывания данных формы с состоянием формы.
  • даже не пытайтесь использовать собственную библиотеку Date. https://date-fns.org/ и https://momentjs.com/ упрощают работу, и это не стоит хлопот

Вот некоторые фрагменты, которые, надеюсь, помогут:

// use a state that includes the somewhere to hold the item being edited and the form values
this.state = { items, itemBeingEdited: -1, form: null };

...
// when you handleEdit set the itemBeingEdited and initialize the form state
handleEdit(key) {
    this.setState({ itemBeingEdited: key, form: this.state.items[key] });
}

...
// keep the form state updated as the items change
 handleOnChange(e) {
    this.setState({
      form: { ...this.state.form, [e.target.name]: e.target.value }
    });
  }

...
// update the cooresponding item and reset form state when item is updated
handleUpdate(event) {
    event.preventDefault();
    const { itemBeingEdited, form } = this.state;
    this.setState({
      items: items.map((item, key) =>
        key === itemBeingEdited
          ? { ...form, dob: moment(form.dob).toDate() }
          : item
      ),
      form: null,
      itemBeingEdited: -1
    });
  }

Мое полное решение можно найти здесь: https://codesandbox.io/s/magical-shadow-v7vp5

1 голос
/ 14 марта 2020

Вы можете попробовать это-

import React from "react";

export default class App extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
      items: [
        { name: "John", dob: "2020-03" },
        { name: "Key", dob: "2010-07" },
        { name: "Mo", dob: "2000-08" }
      ],
      currentItem: {},
      currentIndex: -1,
      editMode: false
    };
    this.dataChanged = this.dataChanged.bind(this);
    this.handleEdit = this.handleEdit.bind(this);
    this.handleDelete = this.handleDelete.bind(this);
    this.handleEditCancel = this.handleEditCancel.bind(this);
    this.handleUpdate = this.handleUpdate.bind(this);
  }
  handleEdit(index) {
    this.setState({
      currentIndex: index,
      editMode: true,
      currentItem: { ...this.state.items[index] }
    });
  }
  handleDelete(key) {
    this.setState({
      items: this.state.items.filter((a, i) => i !== key)
    });
  }
  handleEditCancel(e) {
    this.setState({
      currentIndex: -1,
      editMode: false,
      currentItem: {}
    });
    e.preventDefault();
  }
  handleUpdate() {
    let items = this.state.items;
    items[this.state.currentIndex] = { ...this.state.currentItem };
    this.setState({
      currentIndex: -1,
      editMode: false,
      currentItem: {},
      items: items
    });
  }
  dataChanged(event){
    let field = event.target.name;
    let currentItem = {...this.state.currentItem};
    currentItem[field] = event.target.value;
    this.setState({currentItem: {...currentItem}});
  }
  render() {
    return (
      <div className="App">
        <ul>
          {this.state.items.map((item, key) => (
            <li key={key}>
              <span> {item.name} </span>
              <span> {item.dob} </span>
              <button
                className="btn btn-light"
                onClick={() => this.handleEdit(key)}
              >
                edit
              </button>
              <button
                className="btn btn-danger"
                onClick={() => this.handleDelete(key)}
              >
                delete
              </button>
            </li>
          ))}
        </ul>
        {this.state.editMode && (
          <form onSubmit={this.handleUpdate}>
            <input
              className=""
              name="name"
              value={this.state.currentItem.name}
              onChange={this.dataChanged}
              placeholder="Celebrant's Name"
              ref={name => (this.name = name)}
              required
            />
            <input
              className=""
              name="dob"
              onChange={this.dataChanged}
              value={this.state.currentItem.dob}
              type="month"
            />

            <button type="submit">update</button>
            <button onClick={e => this.handleEditCancel(e)}>cancel</button>
          </form>
        )}
      </div>
    );
  }
}

https://codesandbox.io/s/react-crud-ujs4i

0 голосов
/ 13 марта 2020

Если я так понимаю, у вас есть: * главный компонент, который содержит компонент, заботящийся о форме * компонент, который заботится о списке элементов * компонент, который заботится о каждом элементе - начнется с itemComponent:

    import React, { Component } from "react";

class Item extends Component {
  state = { item: this.props.value };

  render() {
    // we suppose that item dont contains duplicate key
    var item = this.state.item;
    return (
      <li key={item.key}>
        <span> {item.name} </span>
        <span> {item.day} </span>
        <span> {item.dob} </span>
        <button
          className="btn btn-light"
          onClick={() => this.props.handleEdit(item)}
        >
          edit
        </button>
        <button
          className="btn btn-danger"
          onClick={() => this.props.handleDelete(item /*or item.key*/)}
        >
          delete
        </button>
      </li>
    );
  }
}

export default Item;

для компонента формы элемента enet:

import React, { Component } from "react";

class ItemForm extends Component {
  state = {
    item: {
      day: "",
      name: "",
      dob: "",
      key: ""
    }
  };

  handleEditCancel(item) {
    console.log(item);
  }
  handleChange() {
    console.log("in handle change");
  }

  render() {
    var item = this.state.item;
    return (
      <form onSubmit={this.handleUpdate}>
        <input
          className=""
          name="name"
          value={/* this section */ item.name}
          placeholder="Celebrant's Name"
          //   ref={name => (this.name = name)}
          onChange={this.handleChange}
          required
        />
        <input
          className=""
          type="number"
          name="day"
          min="1"
          max="31"
          value={item.day}
          onChange={this.handleChange}
          //   ref={day => (this.day = day)}
          placeholder="day"
        />
        <input
          className=""
          name="dob"
          onChange={this.handleChange}
          type="month"
          value={item.dob}
        />

        <button type="submit">update</button>

        {/* <button onClick={() => this.props.handleEditCancel(this.state.option)}></button>  */}
        <button onClick={this.handleEditCancel}>cancel</button>
      </form>
    );
  }
}

export default ItemForm;

для элементов основных компонентов:

import React, { Component } from "react";
import ItemForm from "./item-form";
import Item from "./item";

class Items extends Component {
  state = { items: [] };
  handleEditCancel(item) {
    // you can either put the edit in the master component or in child component but I prefer the master component take care of all his child delete add or modify any items
    console.log(item);
  }
  handleEdit(item) {
    console.log("handle edit", item);
  }
  handleDelete(item) {
    console.log("handle delete", item);
  }
  componentDidMount() {
    var items = [
      { Key: 1, day: 1, name: "name1", dob: "dob1" },
      { Key: 2, day: 2, name: "name2", dob: "dob2" },
      { Key: 3, day: 3, name: "name3", dob: "dob3" }
    ];
    this.setState({ items: items });
  }
  render() {
    // we suppose that the each item contain a property Key
    return (
      <div>
        <ItemForm
          handleEditCancel={this.handleEditCancel.bind(this)}
        ></ItemForm>
        <div>
          {this.state.items.map(item => (
            <Item
              key={item.Key}
              value={item}
              // add button here update and delete
              handleEdit={this.handleEdit.bind(this)}
              handleDelete={this.handleDelete.bind(this)}
            />
          ))}
        </div>
      </div>
    );
  }
}

export default Items;

после создания другого компонента для входов и кнопки. Идея состоит в том, что главные компоненты должны позаботиться обо всем, о любом обновлении, добавлении или удалении действий и передавать информацию дочерним элементам и реквизитам. надеюсь, это поможет.

...