我是ReactJS的新手,并试图了解如何使用最佳实践来完成基本概念。下面的代码将呈现项目列表,当单击某个项目时,切换有状态 组件并将数据从 传递到 状态对象在重新渲染之前被消费。
我需要帮助的是从下面的数组示例中检索兄弟姐妹数据的方法。为上一个/下一个项目提取数据后, 组件可以访问数据。可以使用键值访问这些兄弟姐妹吗?如果是这样,我将如何使用密钥?
数据:
window.Seed = (function() {
const projects = [
{id:1, title:'Project 1', description:'Project 1 Description'},
{id:2, title:'Project 2', description:'Project 2 Description'},
{id:3, title:'Project 3', description:'Project 3 Description'}
]
};
REACT CODE:
class ProjectList extends React.Component {
state = {
projects: [],
isOpen: false,
modalTitle: '',
modalDescription: '',
modalId: ''
}
componentDidMount() {
this.setState({ projects: Seed.projects });
}
handleModalOpen = (id, title, description) => {
this.setState({
isOpen: true,
modalId: id,
modalTitle: title,
modalDescription: description
});
};
handleModalClose = () => {
this.setState({ isOpen: false });
};
render() {
const projects = this.state.projects;
// GOAL #1: Pass previous/next project data as props
// =================================================
// Pass projects.map data from previous & next siblings
// to the current component or explore a new method to
// retrieve data from state? I can already tell that this
// probably is not the most dynamic approach to handle
// previous/next data.
const projectComponents = projects.map((project) => (
<Project
key={'project-' + project.id}
id={project.id}
title={project.title}
url={project.url}
description={project.description}
background={project.background}
onModalOpen={this.handleModalOpen}
prevTitle={???}
nextTitle={???}
prevDescription={???}
nextDescription={???}
/>
));
if (this.state.isOpen) {
return (
<Modal
id={this.state.modalId}
title={this.state.modalTitle}
description={this.state.modalDescription}
onModalClose={this.handleModalClose}
/>
);
} else {
return (
<div className="projects-container">
<div id="projects" className="wrapper">
{projectComponents}
</div>
</div>
);
}
}
}
class Project extends React.Component {
render() {
return (
<aside className='item'>
<a onClick={this.props.onModalOpen.bind(
this, this.props.id, this.props.title, this.props.description
// I think that I need to bind previous/next data here on click.
// this.props.prevTitle, this.props.nextTitle
// this.props.prevDescription, this.props.nextDescription
)}>
<img src={this.props.background} />
</a>
</aside>
);
}
}
class Modal extends React.Component {
render() {
return (
<div className="modal">
// GOAL #2: Get sibling data from mapped array
// =================================================
// I would like to be able to pass previous and next
// project data as props to populate these headings.
<h2>Current Project: {this.props.title}</h2>
<h2>Previous Project: {this.props.prevTitle} </h2>
<h2>Next Project: {this.props.nextTitle} </h2>
// GOAL #3: Replace content with data stored in state
// =================================================
// I would like to be able to 'onClick' these buttons
// to replace the content of the <Modal />. Essentially,
// this should behave like a lightbox or carousel.
// Initial Project Description
<p>{this.props.description}</p>
// this.props.description = this.props.prevDescription
<button onClick={???}>Previous Project</button>
// this.props.description = this.props.nextDescription
<button onClick={???}>Next Project</button>
<button onClick={this.props.onModalClose}>Close Modal</button>
</div>
);
}
}
感谢阅读!
答案 0 :(得分:0)
作为一般原则,数据应该通过React组件从父到子流动,而不是从兄弟到兄弟。从理论上讲,有可能在兄弟姐妹之间传递数据,但这会使数量级更复杂。自上而下数据流的优点在于,无论父项中的数据发生更改,子项都会(可能会排除纯渲染等优化)重新渲染。因此,您只需更改父级中的数据,子级将根据需要自动更新。以下是以这种方式实现目标的建议。这并不完美,但我希望它说明了这一点:
目标#1:Array.prototype.map
使用以下参数的函数:function(currentValue, index, array) {...}
。对于每个项目,上一个项目为array[index - 1]
,下一个项目为array[index + 1]
。您所要做的就是在map函数中以这种方式引用上一个和下一个项目,以获取它们的标题,描述等。
目标#2:使用this.state.isOpen
而不是this.state.activeProject
。单击项目时,将this.state.activeProject
设置为该项目的索引。然后,如果!!this.state.activeProject
(如果this.state.activeProject
是真实的),您可以推断模态是打开的。使用activeProject
id / index将所需数据从该项目传递到ProjectList
组件呈现方法中的Modal组件。
目标#3:将this.state.activeProject
更新为上一个或下一个项目的索引/ ID。这将导致使用新道具重新渲染ProjectList
。为此,您需要传递onNextClick
和onPrevClick
道具。您可以分别将this.state.activeProject + 1
和this.state.activeProject - 1
部分应用于onNextClick
和onPrevClick
。