Как получить объекты в массиве объектов в React Native - PullRequest
0 голосов
/ 19 сентября 2018

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

{
 "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>

Возможно ли получить доступ к этим объектам в массиве "тегов"?

Ответы [ 5 ]

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

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

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>
})}
0 голосов
/ 19 сентября 2018

Вот полный рабочий код.Поскольку ваше свойство labels state является объектом, вам необходимо как-то отобразить его.Я выбрал 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>
0 голосов
/ 19 сентября 2018

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

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

Вы можете попробовать 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.log(tags);

/* tags = [
  {
    "name": "#twitter"
  },
  {
    "name": "#myspace"
  },
  {
    "name": "#instagram"
  },
  {
    "name": "#facebook"
  }
] */
0 голосов
/ 19 сентября 2018

да, вы можете вызывать теги следующим образом 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>
      )
}
...