Как получить объекты в массиве объектов в React Native

Я как бы потерял доступ к информации в моих статических данных. Вот данные:

{
 "info1": {
    "label": "label",
    "class": "class-css",
    "title": "title",
    "text": "text",
    "number": "20",
    "tags": [
         {
            "name": "#twitter"
        },
        {
            "name": "#myspace"
        }
    ]
 },
 "info2": {
    "label": "label",
    "class": "class-css",
    "title": "title",
    "text": "text",
    "number": "20",
    "tags": [
         {
            "name": "#instagram"
        },
        {
            "name": "#facebook"
        }
    ]
  }
}

Тогда я получаю такую ​​первую информацию:

this.setState({
    currentLabel: this.state.labels["info1"]
})

Вот почему я хочу, а затем я хочу отображать информацию в компоненте, и он работает, пока я не попытаюсь получить информацию tags. Я попробовал .map(), но безуспешно и без ошибок.

<View>
   <Text>{infoDetail.title}</Text>
   <Text>{infoDetail.text}</Text>
   <Text>How do I get "tags" information</Text>
</View>

Можно ли получить доступ к этим объектам в массиве «теги»?

Не могли бы вы поделиться кодом, который вы пробовали с .map, я попробовал ваш JSON с .map, и он работал нормально.

Prasun 19.09.2018 18:04

Если я попробую это, и у меня будет "undefined": const tagsItems = this.state.currentLabel.tags.map((tag, index) => { return <Text key = {index}>{tag.name}</Text> }) Если я сделаю так, то все заработает: const tagsItems = this.state.labels["r1"].tags.map((tag, index) => { return <Text key = {index}>{tag.name}</Text> })

Clément CREUSAT 19.09.2018 21:32
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
В настоящее время производительность загрузки веб-сайта имеет решающее значение не только для удобства пользователей, но и для ранжирования в...
Безумие обратных вызовов в javascript [JS]
Безумие обратных вызовов в javascript [JS]
Здравствуйте! Юный падаван 🚀. Присоединяйся ко мне, чтобы разобраться в одной из самых запутанных концепций, когда вы начинаете изучать мир...
Система управления парковками с использованием HTML, CSS и JavaScript
Система управления парковками с использованием HTML, CSS и JavaScript
Веб-сайт по управлению парковками был создан с использованием HTML, CSS и JavaScript. Это простой сайт, ничего вычурного. Основная цель -...
JavaScript Вопросы с множественным выбором и ответы
JavaScript Вопросы с множественным выбором и ответы
Если вы ищете платформу, которая предоставляет вам бесплатный тест JavaScript MCQ (Multiple Choice Questions With Answers) для оценки ваших знаний,...
1
2
12 765
5
Перейти к ответу Данный вопрос помечен как решенный

Ответы 5

да, вы можете вызывать теги следующим образом: infoDetail.tags и делать на нем карту

render(){
      const tagItems = infoDetail && infoDetail.tags.map((item, index) => {
          return <Text key = {index}>{item.name}</Text>
      });
      return(
        <View>
          <Text>{infoDetail.title}</Text>
          <Text>{infoDetail.text}</Text>
          {tagItems}
        </View>
      )
}

Дело в том, что я использую функциональный (без сохранения состояния) компонент, поэтому я передаю свои реквизиты: <LabelDetail infoDetail = {this.state.currentLabel} />, затем я использую infoDetail для отображения каждой информации .. но map() не работает

Clément CREUSAT 19.09.2018 21:40

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

Hemadri Dasari 20.09.2018 03:29

Наверное, как-то так. <Text>{infoDetail.tags.map(tag => {/*render */})}</Text>

Вы можете попробовать Object.keys() и Array.prototype.reduce(), чтобы получить свои любимые данные:

const data = {
 "info1": {
    "label": "label",
    "class": "class-css",
    "title": "title",
    "text": "text",
    "number": "20",
    "tags": [
         {
            "name": "#twitter"
        },
        {
            "name": "#myspace"
        }
    ]
 },
 "info2": {
    "label": "label",
    "class": "class-css",
    "title": "title",
    "text": "text",
    "number": "20",
    "tags": [
         {
            "name": "#instagram"
        },
        {
            "name": "#facebook"
        }
    ]
  }
};

const tags = Object.keys(data).reduce((result, key) => {
  return result.concat(data[key].tags);
}, [])

console.info(tags);

/* tags = [
  {
    "name": "#twitter"
  },
  {
    "name": "#myspace"
  },
  {
    "name": "#instagram"
  },
  {
    "name": "#facebook"
  }
] */
Ответ принят как подходящий

Вот полный рабочий код. Поскольку ваше свойство состояния labels является объектом, вам нужно как-то сопоставить его. Я выбрал здесь Object.values. Вы можете использовать Object.keys или даже Object.entries в соответствии с вашими потребностями.

Я использовал отдельный компонент Info и передавал ему значения, а затем выполнял рендеринг. В этом компоненте мы снова отображаем tags, а затем визуализируем список.

class App extends React.Component {
  state = {
    labels: {
      info1: {
        label: "label1",
        class: "class-css",
        title: "title",
        text: "text",
        number: "20",
        tags: [
          {
            name: "#twitter",
          },
          {
            name: "#myspace",
          },
        ],
      },
      info2: {
        label: "label2",
        class: "class-css",
        title: "title",
        text: "text",
        number: "20",
        tags: [
          {
            name: "#instagram",
          },
          {
            name: "#facebook",
          },
        ],
      },
    },
  }

  render() {
    const { labels } = this.state;
    return (
      <div>
        {
          Object.values( labels ).map( value =>
            <Info label = {value} key = {value.label} /> )
        }
      </div>
    );
  }
}

const Info = ( props ) => {
  const { title, text, tags } = props.label;
  const tagList = tags.map( tag => <p key = {tag.name}>{tag.name}</p> );
  return (
    <div style = {{ border: "1px solid gray", marginTop: "-1px" }}>
      <p>{title}</p>
      <p>{text}</p>
      <div>{tagList}</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>

Обновлять

Если ваши данные полностью статичны, тогда метод @Xavi A. - хороший вариант. Я не знаю, как поживает ваш список, но я предоставляю простой код, включающий что-то вроде того, что вы хотите здесь.

const labels = {
  info1: {
    label: "label1",
    class: "class-css",
    title: "title",
    text: "text",
    number: "20",
    tags: [
      {
        name: "#twitter"
      },
      {
        name: "#myspace"
      }
    ]
  },
  info2: {
    label: "label2",
    class: "class-css",
    title: "title",
    text: "text",
    number: "20",
    tags: [
      {
        name: "#instagram"
      },
      {
        name: "#facebook"
      }
    ]
  }
};

class App extends React.Component {
  state = {
    currentLabel: Object.keys(labels)[0]
  };

  handleInfoChange = info => this.setState({ currentLabel: info });

  renderList = () => (
    <ul>
      {Object.keys(labels).map(info => (
        <Item key = {info} info = {info} onClick = {this.handleInfoChange} />
      ))}
    </ul>
  );

  render() {
    const { currentLabel } = this.state;
    return (
      <div>
        {this.renderList()}
        <Info currentLabel = {currentLabel} />
      </div>
    );
  }
}

const Item = props => {
  const { info, onClick } = props;
  const handleClick = () => onClick(info);
  return <li onClick = {handleClick}>{info}</li>;
};

const Info = props => {
  const { currentLabel } = props;
  const { title, text, tags } = labels[currentLabel];
  const tagList = tags.map(tag => <p key = {tag.name}>{tag.name}</p>);
  return (
    <div style = {{ border: "1px solid gray", marginTop: "-1px" }}>
      <p>{title}</p>
      <p>{text}</p>
      <div>{tagList}</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>

Он работает, но отображает все данные, а не только первый (текущий / выбранный ярлык), но спасибо, это хороший пример, которому я могу следовать !!

Clément CREUSAT 19.09.2018 22:06

Добро пожаловать. Итак, есть ли список, который вы можете выбрать? Конечно, что-то можно написать по этому случаю.

devserkan 19.09.2018 22:12

Дело в том, что у меня есть этот список с «info1, info2, ... и т. д.». Я хочу, чтобы был выбран первый элемент, а затем я буду управлять состоянием с помощью onPress на нескольких элементах, чтобы переключаться между info1 или info4, или info5 ... currentLabel изменится ;-)

Clément CREUSAT 19.09.2018 22:26

Хорошо, ваши данные полностью статичны или вы получаете их асинхронно откуда-то еще?

devserkan 19.09.2018 22:40

спасибо @devserkan. Теперь я полностью понял! Все работает нормально. Итак, наконец, я использую this.setState({currentLabel: Object.values(labelsInfo)[0]}), ... и я даже могу .map() мой tags. Так круто. Знаешь, я все еще учусь, и иногда я не понимаю, что делаю, а иногда что-то получалось, и я не помню, как :-)

Clément CREUSAT 19.09.2018 23:41

В данном случае это полностью статические данные. У меня есть другие компоненты с API Call с Axios, но он работает. Спасибо еще раз

Clément CREUSAT 19.09.2018 23:42

Добро пожаловать. Если что-то нечеткое, не стесняйтесь спрашивать здесь. Я могу объяснить немного больше. Если вы новичок, настоятельно рекомендую Официальная документация React. Для других вещей, таких как map, Object.keys, пусть MDN будет вашим другом, близким :)

devserkan 19.09.2018 23:49

Нет необходимости сохранять все статические данные в вашем состоянии, вы можете сохранить свое состояние в чистоте, просто сохранив выбранную метку:

onLabelSelect = label => {
    //label will be "info1" for example
    this.setState({
        currentLabel: label 
    })
}

Затем в вашем рендере:

render(){ 
    //get infoDetail from staticData 
    const infoDetail = staticData[this.state.currentLabel]         
    return (
        <View>
            <Text>{infoDetail.title}</Text>
            <Text>{infoDetail.text}</Text>
            {infoDetail.tags.map( ({name}) => <Text>name</Text>)}
        </View>
    )
}

Примечание о карте. Этот:

{infoDetail.tags.map( ({name}) => <Text>name</Text>)}

это более короткая версия:

{infoDetail.tags.map( item => {
    return <Text>item.name</Text>
})}

Другие вопросы по теме