- React Components
- Christopher Pitt
- 887字
- 2021-07-09 19:34:45
Nesting components
Let's think about how we want to structure the components of our interface. Many content management systems feature lists of items—items that we store in and retrieve from a database. For example, let's imagine a system through which we can manage the pages of a website.
For such a system, we need an entry-point—something like PageAdmin
, which connects our persistence layer to our interface:
import React from "react"; class PageAdmin extends React.Component { render() { return <ol>...page objects</ol>; } } export default PageAdmin;
We can also represent the persistence layer in the form of a backend class:
class Backend { getAll() { // ...returns an array of pages } update(id, property, value) { // ...updates a page } delete(id) { // ...deletes a page } }
Note
Later, we'll look at ways of persisting this data. For now, it's OK to just use static data in this class.
We could connect PageAdmin
to this class by proving an instance of Backend
as a property:
var backend = new Backend();
ReactDOM.render(
<PageAdmin backend={backend} />,
document.querySelector(".react")
);
Now, we can start using the Backend
data in our PageAdmin
component:
class PageAdmin extends React.Component { constructor(props) { super(props); this.state = { "pages": [] }; } componentWillMount() { this.setState({ "pages": this.props.backend.getAll() }); } render() { return <ol> {this.state.pages.map(function(page) { return <li key={page.id}>a new page</li> })} </ol>; } }
Note
The truth is that we don't really need to define a default state, or store the page objects to the state. I've done so to demonstrate the idiomatic way of defining initial component state and overriding state when working with ES6-style components.
There's a lot going on here, so let's break it down bit-by-bit:
- We made a constructor. In the constructor, we defined the initial state of a component. We defined the state as an object with an empty
pages
array. - React will call a few magic methods in the life cycle of a component. We used
componentWillMount
to get an array of pages, so we have something to render. We also passed this array of pages to thesetState
method. This exists to store state data and update the markup of a component at the same time. Thethis.state.pages
method will now contain the array of pages from the backend. - When we use curly braces inside markup, it acts like a dynamic value (just like with properties). We can use the
Array.prototype.map
method to return a new element for each page in the array of pages. This will return a new list ofli
components. React also expects components in a list to have a specialkey
property, which it uses to identify them. React uses this to track which components it can remove, add, or change efficiently.Note
The code references
page.id
. The pages returned by the backend should have theid
,title
, andbody
properties for these examples to work.
Let's concentrate on how to show each page through the content management system. The PageAdmin
renders each page as a list item, so let's think about what we want to do inside each list item. I think it makes sense to have a non-interactive summary of each page. Think of a tabular view of all pages in a website:
- Home
- Products
- Terms of service
- Contact us
So there's one aspect to pages that is static: the view of the page title. Perhaps we can also include links to edit or delete each page.
We also want to be able to update each page. We're probably going to need some sort of form, with text inputs for each field we might want to update.
We can represent these two scenarios in a single component:
import React from "react"; class Page extends React.Component { constructor(props) { super(props); this.state = { "isEditing": false }; } render() { if (this.state.isEditing) { return <PageEditor />; } return <PageView />; } } export default Page;
Now, we can switch between the different components, based on whether we're editing or not. Of course, we also need to define these new components:
import React from "react"; class PageEditor extends React.Component { render() { return <form> <input type="text" name="title" /> <textarea name="body"></textarea> <button>back</button> </form>; } } export default PageEditor;
Note that we can define input elements in a way you might expect, if you've worked with HTML markup before. We'll revisit this component later, so don't worry about the details just yet.
The preview mode, for this component, is a little similar:
import React from "react"; class PageView extends React.Component { render() { return <p> {this.props.title} <button>edit</button> <button>delete</button> </p>; } } export default PageView;
This raises an interesting question. How can we efficiently transfer properties from one component to another? ES6 provides a great tool for this in the form of a language feature called the spread operator. First, we need to provide pages to page components in PageAdmin
:
render() {
return <ol>
{this.state.pages.map(function(page) {
return <li key={page.id}>
<Page {...page} />
</li>;
})}
</ol>;
}
We're replacing a new page
with the Page
component we created earlier. We use the spread operator to assign each object key as a component property. We can repeat this concept in Page
:
render() { if (this.state.isEditing) { return <PageEditor {...this.props} />; } return <PageView {...this.props} />; }
The {...this.props}
expands the page object keys. The page.id
becomes this.props.id
inside the PageEditor
and PageView
components. This method is great for transferring many properties; we don't need to write out each one.
- Kibana Essentials
- Microsoft Exchange Server PowerShell Cookbook(Third Edition)
- PyTorch Artificial Intelligence Fundamentals
- 編寫高質(zhì)量代碼:改善C程序代碼的125個(gè)建議
- Eclipse Plug-in Development:Beginner's Guide(Second Edition)
- Mastering KnockoutJS
- PHP+Ajax+jQuery網(wǎng)站開發(fā)項(xiàng)目式教程
- Django 3.0入門與實(shí)踐
- Hands-On Neural Network Programming with C#
- Tableau Desktop可視化高級(jí)應(yīng)用
- 監(jiān)控的藝術(shù):云原生時(shí)代的監(jiān)控框架
- 你真的會(huì)寫代碼嗎
- 零基礎(chǔ)學(xué)Java第2版
- SQL Server實(shí)例教程(2008版)
- Learning Redux