Отображение объекта состояния и тестирование нескольких вложенных массивов без нескольких возвращаемых значений? - PullRequest
0 голосов
/ 21 октября 2019

Я (очевидно) очень плохо знаком с React и Javascript, поэтому заранее извиняюсь, если это глупый вопрос. В основном у меня есть массив объектов в this.state, каждый из которых имеет свой собственный вложенный массив, например:

    foods: [
      {
        type: "sandwich",
        recipe: ["bread", "meat", "lettuce"]
      },
      {
        type: "sushi",
        recipe: ["rice", "fish", "nori"]
      }, ...

Я уже написал функцию, которая отображает объекты состояния и запускает .include ()на каждый object.recipe, чтобы увидеть, если он содержит строку.

    const newArray = this.state.foods.map((thing, i) => {
      if (thing.recipe.includes(this.state.findMe)) {
        return <p>{thing.type} contains {this.state.findMe}</p>;
      } return <p>{this.state.findMe} not found in {thing.type}</p>;
    });

Основная проблема заключается в том, что .map () возвращает значение для каждого элемента в массиве, и я этого не хочу. Мне нужно иметь функцию, которая проверяет каждый объект. Recipe, возвращает совпадение, если оно находит (как описано выше), но также возвращает сообщение «Нет совпадений найдено», если ни один из вложенных массивов содержит значение, которое он ищет. Прямо сейчас эта функция возвращает «{this.state.findMe}, не найденный в {thing.type}» для каждого объекта в массиве.

Я знаю, что .map () должен возвращать значение. Я попытался использовать forEach () и .filter () вместо этого, но я не мог заставить синтаксис работать. (Также я не могу понять, как сделать эту функцию функциональным компонентом без сохранения состояния - я могу заставить его работать, только если я добавлю его в метод render () - но это не моя настоящая проблема здесь.)

class App extends React.Component {
  state = {

    foods: [
      {
        type: "sandwich",
        recipe: ["bread", "meat", "lettuce"]
      },
      {
        type: "sushi",
        recipe: ["rice", "fish", "nori"]
      },
      {
        type: "chili",
        recipe: ["beans", "beef", "tomato"]
      },
      {
        type: "padthai",
        recipe: ["noodles", "peanuts", "chicken"]
      },
    ],

    findMe: "bread",

  }

  render() {

    const newArray = this.state.foods.map((thing, i) => {
      if (thing.recipe.includes(this.state.findMe)) {
        return <p>{thing.type} contains {this.state.findMe}</p>;
      } return <p>{this.state.findMe} not found in {thing.type}</p>;
    });

   return (
     <div>
       <div>
         <h3>Results:</h3>
             {newArray}
       </div>
    </div>
    )
  }
};

1 Ответ

0 голосов
/ 21 октября 2019

Вы можете использовать Array.reduce для этого:

const result = foods.reduce((acc,curr)=> curr.recipe.includes(findMe) ? `${curr.type} contains ${findMe}`:acc ,'nothing found')

console.log(result)

Хотя, если ингредиент найден в более чем одном рецепте, он вернет только последний.

В качестве альтернативы, вы могли быиспользуйте map и filter:

const result = foods.map((thing, i) => {
      if (thing.recipe.includes(findMe)) {
        return `${thing.type} contains ${findMe}`;
      }}).filter(val=>!!val)

console.log(result.length?result[0]:'nothing found')
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...