Здравствуйте! Вопрос касается связи между компонентами React,а именно: передача данных из одного компонента в другой.
Пусть есть страница <Layout/>, у которой есть массив объектов items. Для каждого элемента items создается компонент <Item />:
Код Layout.jsx:
class Layout extends Component {
renderItems() {
var items = [
{name: 'Ivan', _id: '1'},
{name: 'Petya', _id: '2'}
];
return items.map( (each) => {
return (
<Item each={each} />
);
});
}
render() {
return (
<main> {this.renderItems} <main>
);
}
}
Код Item.jsx:
class Item extends Component {
render() {
return (
<div>
{this.props.each.name}
</div>
);
}
}
Пусть теперь я хочу реализовать по щелчку на каждый <Item />вывод в консоль его _id. Сделать это внутри самого <Item /> не составляет никакого труда:
Новый код Item.jsx:
class Item extends Component {
printId() {
console.log(this.props.each._id);
}
render() {
return (
<div onClick={ this.props.printId.bind(this) }>
{this.props.each.name}
</div>
);
}
}
Но как быть, если нужно реализовать кнопку "Показать _id" снаружи, то есть в <Layout /> ?
Допустим, внутри каждого <Item/> добавим checkbox. Если этот чекбокс отмечен галочкой как selected, то при нажатии кнопки 'Показать _id' в консоль выводятся _id всех отмеченных Itemов.
Но как передать _id отмеченных Itemов в <Layout /> ?
Заранее благодарен за ответы.
Ответ нашелся сразу в документации, спасибо @AlexeyTen за наводку. Пришлось помучиться, однако решение готов и оно ниже.
При вызове функции из компонента someFunction.bind(this) мы можем передавать любое количество аргументов: someFunction.bind(this, arg1, arg2, ...). В этом и заключается ответ.
Для примера выше: добавим функцию printId в компонент <Layout /> и навесим на компонент <Item /> вызов printId по событию onClick. В качестве аргумента в функцию будем передавать текущий _id элемента. Новый код Layout.jsx:
class Layout extends Component {
printId(id)
console.log(id);
renderItems() {
var items = [
{name: 'Ivan', _id: '1'},
{name: 'Petya', _id: '2'}
];
return items.map( (each) => {
const eachId = each._id;
return (
<Item onClick={this.printId.bind(this, eachId)} each={each} />
);
});
}
render() {
return (
<main> {this.renderItems} <main>
);
}
}
Однако, код выше не будет работать. Причина в том, что <Item /> это не настоящий DOM-элемент, соответственно и события OnClick у него быть не может. В строке <Item onClick={this.printId.bind(this, eachId)} /> onCLick является обычным props. Для того, чтобы этот код работал, как ожидается, нужно внутри компонента <Item /> у настоящего DOM-элемента прописать передачу настоящему onClick нашу функцию из props:
class Item extends Component {
render() {
return (
<div onClick={this.props.onClick}>
{this.props.each.name}
</div>
);
}
}
Теперь все работает как надо.
Продвижение своими сайтами как стратегия роста и независимости