2016-02-19 67 views
0

我有应用程序,具有布局组分,其主要成分,它有两个书架组件和每个书架部件具有五个组件。我怎样才能例如改变第二书架,第五 state.taken到真正布局组件?如何更改特定的子组件的状态,通过祖父母组件?

它看起来是这样的:

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> 
    ); 
    } 
} 

回答

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> 
    ); 
    } 
} 
0

搞清楚道具/州应该exi st可能是使用React最具挑战性和有趣的部分。作为哲学的指导,我会很好地看看Thinking In React指南。

但是要简单回答你的问题;

数据应始终作为需要访问它的最高级别组件中的状态存在。因此,对于此示例,您书籍的实际数据应作为Layouts组件上的状态元素存在。

数据以道具的形式传递给儿童,并被低层认为是不可改变的。即,您的书架和书籍组件将无法直接修改其拥有的图书数据。相反,他们将使用道具回调Layouts,这将对其状态中的数据执行操作,并因此将更新其子项的道具,从而导致适当的重新渲染。

React中的数据是单向的,从父到子。儿童组件应该永远不需要询问父母的任何事情。父母应该提供孩子们需要的一切道具。

相关问题