#javascript #arrays #reactjs
#javascript #массивы #reactjs
Вопрос:
У меня есть данные, хранящиеся в data.js файл в массиве. Я показываю эти данные в дочернем компоненте (только первый объект в массиве). Я хочу отобразить через тот же массив в родительском компоненте (путем рендеринга <ChildComponent>
). Как я могу это сделать?
data.js
export default {
accordionItems: [
{
id: 1,
title: 'Why is my car not green?',
answer: 'We ran out of green color',
},
{
id: 2,
title: 'Where have all the drivers gone?',
answer: 'It's lunch time',
},
{
id: 3,
title: 'Do you have a book of complains',
answer: 'You can write at info@mail.eu',
},
],
};
дочерний компонент
import Data from './data';
class AccordionItem extends Component {
constructor(props) {
super(props);
this.state = {
question: Data.accordionItems[0], //if I remove [0], no data is rendered
};
}
return (
<div >
<div>
<p>{question.title}</p>
<button>toggle</button>
</div>
<p>{question.answer}</p>
<hr />
</div>
);
Родительский компонент
import AccordionItem from './AccordionItem';
import Data from './data';
class Accordion extends Component {
constructor(props) {
super(props);
this.state = {
accordionItems: Data.accordionItems,
};
}
render() {
const { accordionItems } = this.state;
return accordionItems.map(accordionItem => (
<AccordionItem key={accordionItem.id} />
Я хочу получить все 3 объекта из массива «данные» в родительском компоненте, теперь я получаю 3 одинаковых компонента только с первым объектом.
Ответ №1:
Передайте элемент в качестве реквизита:
<AccordionItem question={accordionItem} ... />
Вы можете получить к нему доступ с помощью метода render():
render() {
const { question } = this.props;
return (
<div >
<div>
<p>{question.title}</p>
<button>toggle</button>
</div>
<p>{question.answer}</p>
</div>
);
}
Вы не должны использовать состояние вообще (пока).
Ответ №2:
Вы можете просто передать данные из самой функции map следующим образом:
accordionItems.map(accordionItem => (
<AccordionItem
key={accordionItem.id}
open={[`isOpen-${accordionItems.id}`]}
data={accordionItem}
/>
));
И в дочернем:
class AccordionItem extends Component {
constructor(props) {
super(props);
this.state = {
question: props.data, //data from map function in parent
};
}
Комментарии:
1. Похоже, это работает для родительского компонента. но дочерний компонент выдает ошибку: не удается прочитать свойство ‘title’ неопределенного
2. В одном элементе мне нужно было передать индекс массива.
<AccordionItem data={Data.accordionItems[0]}
Все в порядке.3. Вот наилучшее возможное решение , на мой взгляд : codesandbox.io/s/y2lrywpk21
Ответ №3:
Возможно, вам следует прочитать немного больше о компонентах и передаче реквизитов в React.
Что вы могли бы сделать, чтобы это сработало, так это вместо импорта Data
в ваш AccordionItem
компонент передать его в AccordionItem
через props.
Это выглядело бы примерно так:
import AccordionItem from './AccordionItem';
import Data from './data';
class Accordion extends Component {
constructor(props) {
super(props);
this.state = {
accordionItems: Data.accordionItems,
};
}
render() {
const { accordionItems } = this.state;
return accordionItems.map(accordionItem => (
<AccordionItem
key={accordionItem.id}
item={accordionItem}
open={[`isOpen-${accordionItems.id}`]}
/>
))
}
Теперь элемент должен стать доступным через реквизиты в дочернем компоненте:
class AccordionItem extends Component {
render(){
const { question } = this.props
return (
<div >
<div>
<p>{question.title}</p>
<button>toggle</button>
</div>
<p>{question.answer}</p>
<hr />
</div>
);
}