我的应用有布局组件,它是主要组件,它有两个 Bookshelf 组件,每个 Bookshelf 组件有五个预订组件。我如何在第二个 Bookshelf ,第五个 Book state.taken更改 true 或 false 中更改< strong>布局组件?
它看起来像这样:
Layout.js
export default class Layout extends React.Component {
render() {
var bookshelves = [
1,2
].map((bookshelf_id, i) => <Bookshelf key={i} bookshelf_id={bookshelf_id}/>);
return (
<div>
{bookshelves}
</div>
);
}
}
Bookshelf.js
export default class Bookshelf extends React.Component {
render() {
var books = [
1,2,3,4,5
].map((book_id, i) => <Book key={i} book_id={book_id}/>);
return (
<table>
<h1>Shelf{this.props.bookshelf_id}</h1>
{books}
</table>
);
}
}
Book.js
export default class Book extends React.Component {
render() {
var style= {
backgroundColor: this.props.taken ? 'red' : 'green'
};
return (
<td style={style}>Book{this.props.book_id}</td>
);
}
}
答案 0 :(得分:1)
嗯,您需要更新示例代码才能在一个架子上更改图书。在您的示例中,每个书架总是具有相同的5本书,具有相同的ID。因此,在此设置中,您无法仅在一个书架上更改书籍。
此外,如果您从祖父母那里传递taken
参数,则它是道具,而不是州。
您可以使用道具并将其转换为初始状态,但这只会意味着之后会有一些用户交互来操纵状态。
最后,在反应中使用映射索引作为key
并不是一个好主意。最好使用唯一的ID。
更新后的代码如下所示:
Layout.js
export default class Layout extends React.Component {
render() {
// library is an array of bookshelf objects
// each bookshelf object contains book objects
// fifth book on second shelf is taken
var library = [
{ id: "shelf1", books: [
{ id: "book11", taken: false },
{ id: "book12", taken: false },
{ id: "book13", taken: false },
{ id: "book14", taken: false },
{ id: "book15", taken: false }]
},
{ id: "shelf2", books: [
{ id: "book21", taken: false },
{ id: "book22", taken: false },
{ id: "book23", taken: false },
{ id: "book24", taken: false },
{ id: "book25", taken: true }]
}
];
var bookshelves = library.map((bookshelf) =>
<Bookshelf key={bookshelf.id}
bookshelf_id={bookshelf.id}
books={bookshelf.books}/>);
return (
<div>
{bookshelves}
</div>
);
}
}
Bookshelf.js
export default class Bookshelf extends React.Component {
render() {
var books = this.props.books.map((book) =>
<Book key={book.id} book_id={book.id} taken={book.taken}/>);
return (
<table>
<h1>{this.props.bookshelf_id}</h1>
{books}
</table>
);
}
}
Book.js
export default class Book extends React.Component {
// put initial taken parameter in state
getInitialState() {
return { taken: this.props.taken }
},
render() {
var style= {
backgroundColor: this.state.taken ? 'red' : 'green'
};
return (
<td style={style}>Book{this.props.book_id}</td>
);
}
}
答案 1 :(得分:0)
确定道具/状态应该存在的位置可能是使用React最具挑战性和最有趣的部分。作为哲学的指南,我会仔细研究Thinking In React指南。
但要简单回答你的问题;
数据应始终作为需要访问它的最高阶组件中的状态存在。因此,对于此示例,有关您图书的实际数据应作为Layouts
组件上的状态元素存在。
数据以道具的形式传递给儿童,并且被较低级别视为不可变。即,您的书架和书籍组件将无法直接修改他们拥有的书籍数据。相反,他们将利用道具回调到Layouts
,它将对其状态中的数据执行操作,因此,将更新其子项的道具,从而导致适当的重新渲染。
React中的数据是单向的,从父级到子级。儿童成分应该永远不需要询问他们父母的任何事情。父母应该提供孩子们作为道具所需的一切。