Реагируйте - проблема с синтаксисом JSX, и как выполнять итерации с картой и отображать элементы на новых строках - PullRequest
0 голосов
/ 13 сентября 2018

Я новичок в React и создаю стиль списка задач Приложение списка рецептов .У меня есть функциональный компонент Item.js, и я использую JSX и функцию карты, чтобы перебирать каждый элемент рецепта и отображать их.Я хочу, чтобы каждый элемент рецепта отображался в новой строке, но когда я использую .map для их итерации, React помещает весь список элементов рецепта в один тег p вместо одного тега p для каждого элемента.

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

Вот мой код:

import React from 'react';
import Button from 'react-bootstrap/lib/Button';


const Item = (props) => (
  <div>
    <div className="Recipe-Item-Container" key={props.text}>

        {props.items.map((item, index) => 
        <div className="Recipe-Item" key={index}>

            <h3>{item}</h3>

            <p>{props.ingredients[index]}</p>

          <div className="buttons-container">
            <Button className="edit-button" onClick={() => props.edit(item, index)}>Edit</Button>
            <Button className="delete-button" onClick={() => props.delete(item, index)}>Delete</Button>
          </div>

        </div>
      )}
    </div>
  </div>
)


export default Item;

Также в строке {props.items.map((item, index) =>, еслиЯ добавляю фигурную скобку после => я получаю ошибку.У меня установлен Reinter / JSX linter, и он ничего не ловит.В чем проблема?

Я знаю, что это, вероятно, ошибка noob, но JSX заставляет меня зацикливаться здесь.

Ответы [ 2 ]

0 голосов
/ 13 сентября 2018

Вот рабочая версия.

class App extends React.Component {
  state = {
    items: [ "Pumpkin Pie", "Spaghetti", "Onion Pie" ],
    ingredients: [
      [ "Pumpkin Puree", "Sweetened Condensed Milk", "Eggs", "Pumpkin Pie Spice", "Pie Crust" ],
      [ "Noodles", "Tomatoe", "Sauce", "Meatballs" ],
      [ "Onion", "Pie Crust" ],
    ],
  }

  render() {
    return (
      <div className="box">
        <Item items={this.state.items} ingredients={this.state.ingredients} />
      </div>
    );
  }
}

const Item = props => (
  <div>
    <div className="Recipe-Item-Container" key={props.text}>

      {props.items.map( ( item, index ) => (
        <div className="Recipe-Item" key={item}>

          <h3>{item}</h3>
          <ul>
            {
              props.ingredients[ index ].map( ingredient =>
                <li key={ingredient}>{ingredient}</li> )
            }
          </ul>


          <div className="buttons-container">
            <button className="edit-button" onClick={() => props.edit( item, index )}>Edit</button>
            <button className="delete-button" onClick={() => props.delete( item, index )}>Delete</button>
          </div>

        </div>
      ) )}
    </div>
  </div>
);

ReactDOM.render(<App />, document.getElementById("root"));
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.min.js"></script>
<div id="root"></div>

Но на вашем месте я бы изменил форму своего состояния.Примерно так:

class App extends React.Component {
  state = {
    items: [
      {
        name: "Pumpkin Pie",
        ingredients: [
          "Pumpkin Puree",
          "Sweetened Condensed Milk",
          "Eggs",
          "Pumpkin Pie Spice",
          "Pie Crust"
        ]
      },
      {
        name: "Spaghetti",
        ingredients: ["Noodles", "Tomatoe", "Sauce", "Meatballs"]
      },
      {
        name: "Onion Pie",
        ingredients: ["Onion", "Pie Crust"]
      }
    ]
  };

  removeItem = item => {
    const newItems = this.state.items.filter(el => el.name !== item.name);
    this.setState({ items: newItems });
  };

  editItem = item => alert(`${item.name} will be edited`);

  renderItems = () =>
    this.state.items.map(item => (
      <Item
        key={item.name}
        item={item}
        removeItem={this.removeItem}
        editItem={this.editItem}
      />
    ));

  render() {
    return <div className="box">{this.renderItems()}</div>;
  }
}

const Item = props => {
  const { item, removeItem, editItem } = props;
  const handleRemove = () => removeItem(item);
  const handleEdit = () => editItem(item);

  return (
    <div>
      <div className="Recipe-Item-Container" key={props.text}>
        <div className="Recipe-Item">
          <h3>{item.name}</h3>
          <ul>
            {item.ingredients.map(ingredient => (
              <li key={ingredient}>{ingredient}</li>
            ))}
          </ul>
          <div className="buttons-container">
            <button className="edit-button" onClick={handleEdit}>
              Edit
            </button>
            <button className="delete-button" onClick={handleRemove}>
              Delete
            </button>
          </div>
        </div>
      </div>
    </div>
  );
};

ReactDOM.render(<App />, document.getElementById("root"));
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.min.js"></script>
<div id="root"></div>

Изменения

  • Форма состояния: Вместо удержания двух массивов мы сохраняем объект для каждого элемента,Этот объект имеет свойства name и ingredients.Может быть, в будущем у него может появиться уникальный id?Объекты являются гибкими.
  • Вместо того, чтобы передавать все элементы в компонент Item, мы сопоставляем элементы в родительском компоненте и передаем только один элемент компоненту Item.
  • У нас все еще есть функции-обработчики, определенные в родительском.Но мы не используем их непосредственно в обратном вызове кнопки с помощью функции стрелки.Таким образом, они не воссоздаются в каждом рендере.Кроме того, нам не нужно использовать индекс для передачи элементов обратно родителю.У нас есть item сама опора!Вы можете увидеть, как мы обрабатываем функцию удаления: с помощью .filter Вы можете применить ту же функцию к другим функциям..map, .filter, Object.assign или распространенный синтаксис - все это хорошие инструменты.Просто избегайте прямого изменения своего состояния.
0 голосов
/ 13 сентября 2018

Если вы добавите фигурные скобки после жирной стрелки, вам придется явно вернуть JSX.

const Item = (props) => (
  <div>
    <div className="Recipe-Item-Container" key={props.text}>

      {props.items.map((item, index) => {
          return (
              <div className="Recipe-Item" key={index}>

              <h3>{item}</h3>

              <p className="ingredients-list">
                   {props.ingredients[index].map((ingredient, ingredientIndex) => {
                      return (
                           <div className="ingredient" key={ingredient}>
                               {ingredient}
                           </div>
                     )
                   }}
              </p>

              <div className="buttons-container">
                <Button className="edit-button" onClick={() => props.edit(item, index)}>Edit</Button>
                <Button className="delete-button" onClick={() => props.delete(item, index)}>Delete</Button>
              </div>

            </div>
          )
        }
      )}
    </div>
  </div>
)
...