原文连接: https://levelup.gitconnected....
在本文中,我想分享几个技巧,这些技巧将改善你的React代码。css
props
在 JS
中解构对象(尤为是 props
)能够大大减小代码中的重复。看下面的例子:react
//Parent Component import React from 'react'; import CoffeeCard from './CoffeeCard'; const CafeMenu = () => { const coffeeList = [ { id: '0', name: 'Espresso', price: '2.00', size: '16' }, { id: '1', name: 'Cappuccino', price: '3.50', size: '24' }, { id: '2', name: 'Caffee Latte', price: '2.70', size: '12' } ]; return coffeeList.map(item => ( <CoffeeCard key={item.id} coffee={item} /> )); }; export default CafeMenu;
CafeMenu
组件用于存储可用饮料的列表,如今咱们想要建立另外一个能够显示一种饮料的组件。若是不对 props
进行解构,咱们的代码将像下面这样:git
//Child Component import React from 'react'; const CoffeeCard = props => { return ( <div> <h1>{props.coffee.name}</h1> <p>Price: {props.coffee.price}$</p> <p>Size: {props.coffee.size} oz</p> </div> ); }; export default CoffeeCard;
如你所见,它看起来并很差,每次咱们须要获取某个属性时,都要重复 props.coffee
,幸运的是,咱们能够经过解构来简化它。shell
//Child Component (after destructuring props) import React from 'react'; const CoffeeCard = props => { const { name, price, size } = props.coffee; return ( <div> <h1>{name}</h1> <p>Price: {price}$</p> <p>Size: {size} oz</p> </div> ); }; export default CoffeeCard;
若是咱们想将大量参数传递给子组件,咱们还能够直接在构造函数(或函数组件的参数)中解构 props
。好比:npm
//Parent Component import React from 'react'; import ContactInfo from './ContactInfo'; const UserProfile = () => { const name = 'John Locke'; const email = 'john@locke.com'; const phone = '01632 960668'; return <ContactInfo name={name} email={email} phone={phone} />; }; export default UserProfile;
//Child Component import React from 'react'; const ContactInfo = ({ name, email, phone }) => { return ( <div> <h1>{name}</h1> <p> E-mail: {email}</p> <p> Phone: {phone}</p> </div> ); }; export default ContactInfo;
有时(尤为是在“容器组件”中),咱们须要使用许多不一样的模块,而且组件导入看上去有些混乱,如:json
import { Auth } from 'aws-amplify'; import React from 'react'; import SidebarNavigation from './components/SidebarNavigation'; import { EuiPage, EuiPageBody } from '@elastic/eui'; import { keyCodes } from '@elastic/eui/lib/services'; import './index.css' import HeaderNavigation from './components/HeaderNavigation'; import Routes from './Routes';
关于导入模块的理想顺序有不少不一样的观点。我建议多参考,而后找到适合你本身的那种。api
至于我本身,我一般按类型对导入进行分组,并按字母顺序对它们进行排序(这是可选操做)。我也倾向于保持如下顺序:数组
快速重构一下,咱们的模块导入看上去舒服多了了。app
import React from 'react'; import { Auth } from 'aws-amplify'; import { EuiPage, EuiPageBody } from '@elastic/eui'; import { keyCodes } from '@elastic/eui/lib/services'; import HeaderNavigation from './components/HeaderNavigation'; import SidebarNavigation from './components/SidebarNavigation'; import Routes from './Routes'; import './index.css'
Fragments
在咱们的组件中,咱们常常返回多个元素。一个 React
组件不能返回多个子节点,所以咱们一般将它们包装在 div
中。有时,这样的解决方案会有问题。好比下面的这个例子中:ide
咱们要建立一个 Table
组件,其中包含一个 Columns
组件。
import React from 'react'; import Columns from './Columns'; const Table = () => { return ( <table> <tbody> <tr> <Columns /> </tr> </tbody> </table> ); }; export default Table;
Columns
组件中包含一些 td
元素。因为咱们没法返回多个子节点,所以须要将这些元素包装在 div
中。
import React from 'react'; const Columns = () => { return ( <div> <td>Hello</td> <td>World</td> </div> ); }; export default Columns;
而后就报错了,由于tr
标签中不能放置 div
。咱们可使用 Fragment
标签来解决这个问题,以下所示:
import React, { Fragment } from 'react'; const Columns = () => { return ( <Fragment> <td>Hello</td> <td>World</td> </Fragment> ); }; export default Columns;
咱们能够将 Fragment
视为不可见的 div
。它在子组件将元素包装在标签中,将其带到父组件并消失。
你也可使用较短的语法,可是它不支持 key
和属性。
import React from 'react'; const Columns = () => { return ( <> <td>Hello</td> <td>World</td> </> ); }; export default Columns;
将应用程序的组件分为展现(木偶)组件和容器(智能)组件。若是你不知道这些是什么,能够下面的介绍:
props
提供,木偶组件中不该该调用API,这是智能组件的工做木偶组件有:加载指示器,模态,按钮,输入。
Redux
,生命周期方法,API和库等等。使用展现组件和容器组件的好处
此外,它还符合“单一责任原则” - 一个组件负责外观,另外一个组件负责数据。
让咱们看一个简单的例子。这是一个 BookList
组件,该组件可从API获取图书数据并将其显示在列表中。
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;
该组件的问题在于,它负责太多事情。它获取并呈现数据。它还与一个特定的接口关联,所以在不复制代码的状况下,不能使用此组件显示特定用户的图书列表。
如今,让咱们尝试将此组件分为展现组件和容器组件。
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;
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
组件。
styled-components
对 React
组件进行样式设置一直是个难题。查找拼写错误的类名,维护大型 CSS
文件,处理兼容性问题有时可能很痛苦。
styled-components
是一个常见的 css in js
类库,和全部同类型的类库同样,经过 js
赋能解决了原生 css
所不具有的能力,好比变量、循环、函数等。
要开始使用 styled-components
,你须要首先安装依赖:
npm i styled-components
下面是一个示例:
import React from 'react'; import styled from 'styled-components'; const Grid = styled.div` display: flex; `; const Col = styled.div` display: flex; flex-direction: column; `; const MySCButton = styled.button` background: ${props => (props.primary ? props.mainColor : 'white')}; color: ${props => (props.primary ? 'white' : props.mainColor)}; display: block; font-size: 1em; margin: 1em; padding: 0.5em 1em; border: 2px solid ${props => props.mainColor}; border-radius: 15px; `; function App() { return ( <Grid> <Col> <MySCButton mainColor='#ee6352' primary>My 1st Button</MySCButton> <MySCButton mainColor='#ee6352'>My 2st Button</MySCButton> <MySCButton mainColor='#ee6352'>My 3st Button</MySCButton> </Col> <Col> <MySCButton mainColor='#515052' primary>My 4st Button</MySCButton> <MySCButton mainColor='#515052'>My 5st Button</MySCButton> <MySCButton mainColor='#515052'>My 6st Button</MySCButton> </Col> </Grid> ); } export default App;
这只是样式化组件如何工做的一个简单示例,可是它们能够作的还远远不止这些。你能够在其官方文档中了解有关样式化组件的更多信息。
谢谢阅读!到此为止。但愿你学到了一些新知识。若是你知道React中的其它提示和技巧,请随时在下面的评论部分中分享它们。