将应用程序的组件分为展示(木偶)组件和容器(智能)组件。
展示组件
- 主要关注UI,它们负责组件的外观。
- 数据由 props 提供,木偶组件中不应该调用API,这是智能组件的工作
- 除了UI的依赖包,它们不需要依赖应用程序
- 它们可能包括状态,但仅用于操纵UI本身-它们不应存储应用程序数据。
木偶组件有:加载指示器,模态,按钮,输入。
容器组件
- 它们不关注样式,通常不包含任何样式
- 它们用于处理数据,可以请求数据,捕获更改和传递应用程序数据
- 负责管理状态,重新渲染组件等等
- 可能依赖于应用程序,调用 Redux,生命周期方法,API和库等等。
使用展示组件和容器组件的好处
此外,它还符合“单一责任原则” - 一个组件负责外观,另一个组件负责数据。
让我们看一个简单的例子。这是一个 BookList 组件,该组件可从API获取图书数据并将其显示在列表中。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33
| import React, { useState, useEffect } from 'react';
const BookList = () => { const [books, setBooks] = useState([]); const [isLoading, setLoading] = useState(false);
useEffect(() => { setLoading(true); fetch('api/books') .then(res => res.json()) .then(books => { setBooks(books); setLoading(false); }); }, []);
const renderLoading = () => { return <p>Loading...</p>; };
const renderBooks = () => { return ( <ul> {books.map(book => ( <li>{book.name}</li> ))} </ul> ); };
return <>{isLoading ? renderLoading() : renderBooks()}</>; }; export default BookList;
|
该组件的问题在于,它负责太多事情。它获取并呈现数据。它还与一个特定的接口关联,因此在不复制代码的情况下,不能使用此组件显示特定用户的图书列表。
现在,让我们尝试将此组件分为展示组件和容器组件。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
| import React from 'react';
const BookList = ({ books, isLoading }) => { const renderLoading = () => { return <p>Loading...</p>; };
const renderBooks = () => { return ( <ul> {books.map(book => ( <li key={book.id}>{book.name}</li> ))} </ul> ); };
return <>{isLoading ? renderLoading() : renderBooks()}</>; }; export default BookList;
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
| import React, { useState, useEffect } from 'react'; import BookList from './BookList';
const BookListContainer = () => { const [books, setBooks] = useState([]); const [isLoading, setLoading] = useState(false);
useEffect(() => { setLoading(true); fetch('/api/books') .then(res => res.json()) .then(books => { setBooks(books); setLoading(false); }); }, []);
return <BookList books={books} isLoading={isLoading} />; };
export default BookListContainer;
|
如你所见,它看起来要好得多。更重要的是,它使我们可以在具有不同数据的许多地方使用 BookList 组件。