4个开发React应用的实用技巧
【相关专题推荐:react面试题(2020)】
背景
Hooks 自推出以来就很火, 它改变了我们编写React 代码的方式, 有助于我们写更简洁的代码。
今天这边文章不是说Hooks的,Hooks之外, 还有很多实用的技巧可以帮助我们编写简洁清晰
的代码。
今天我就整理了几个使用的技巧,其中有些也是我在公司项目中实践的
,现在整理出来分享给大家, 希望对大家有所启发
。
正文
1. 使用字符串来定义一个React元素
举个简单的例子:
// 我们可以通过把一个字符串'p' 赋值给一个变量, 就像: import React from 'react' const MyComponent = 'p' function App() { return ( <> <MyComponent> <h3>I am inside a {'<p />'} element</h3> </MyComponent> </> ) }
React 内部会调用 React.createElement
, 使用这个字符串来生成这个元素。
另外, 你也可以显式的定义component
来决定渲染的内容, 比如:
// 定义一个MyComponent function MyComponent({ component: Component = 'p', name, age, email }) { return ( <Component> <h1>Hi {name} </h1> <> <h6>You are {age} years old</h6> <small>Your email is {email}</small> </> </Component> ) }
适用方式:
function App() { return ( <> <MyComponent component="p" name="KK" age={18} email="xxx@gmail.com"> </> ) }
这种方式, 你也可以传入一个自定义的组件, 比如:
function Dashboard({ children }) { return ( <p style={{ padding: '25px 12px' }}> {children} </p> ) } function App() { return ( <> <MyComponent component={Dashboard} name="KK" age={18} email="xxx@gmail.com"> </> ) }
如果你遇到处理一类相似的
元素或者组件,可以通过这种自定义的方式抽象出来,简化你的代码。
举个现实的例子:
比如我们现在要做一个货物打包的需求, 可以单个打, 也可以批量打, 针对共同点可以写自定义组件:
import React from 'react' import withTranslate from '@components/withTranslate' import PackComponent from './PackComponent' import usePack, { check } from './usePack' let PackEditor = (props) => { const packRes = usePack(props) return ( <PackComponent {...packRes} /> ) } PackEditor = withTranslate(PackEditor) PackEditor.check = check export default PackEditor
这样在不同的业务模块中, 就可以灵活的使用了, 非常方便。
2. 定义错误边界
在Javascript里,我们都是使用 try/catch
来捕捉可能发生的异常,在catch
中处理错误。 比如:
function getFromLocalStorage(key, value) { try { const data = window.localStorage.get(key) return JSON.parse(data) } catch (error) { console.error } }
这样, 即便发生了错误, 我们的应用也不至于崩溃白屏。
React 归根结底也是Javascript,本质上没什么不同, 所以同样的使用try/catch
也没有问题。
然而, 由于React 实现机制的原因, 发生在组件内部的Javascript 错误会破坏内部状态, render会产生错误:
https://github.com/facebook/react/issues/4026
基于以上原因,React 团队引入了Error Boundaries
:
https://reactjs.org/docs/error-boundaries.html
Error boundaries
, 其实就是React组件, 你可以用找个组件来处理它捕捉到的任何错误信息。
当组件树崩溃的时候,也可以显示你自定义的UI,作为回退。
看 React 官方提供的例子:
https://reactjs.org/docs/error-boundaries.html#introducing-error-boundaries
class ErrorBoundary extends React.Component { constructor(props) { super(props) this.state = { hasError: false } } static getDerivedStateFromError(error) { // Update state so the next render will show the fallback UI. return { hasError: true } } componentDidCatch(error, errorInfo) { // You can also log the error to an error reporting service logErrorToMyService(error, errorInfo) } render() { if (this.state.hasError) { // You can render any custom fallback UI return <h1>Something went wrong.</h1> } return this.props.children } }
使用方式:
<ErrorBoundary> <MyWidget /> </ErrorBoundary>
Live Demo By Dan Abramov:
https://codepen.io/gaearon/pen/wqvxGa?editors=0010
3.高阶组件
通俗点讲, 所谓高阶组件就是, 你丢一个组件进去, 增加一些属性或操作, 再丢出来。
一般来说, 你可以把一些具备共同点的
组件抽象成一个高阶组件
, 然后再不同的模块中复用
。
比如, 我们的系统中, 有一类按钮要加个border
, 很多地方都要用到, 我们把它抽象出来:
import React from 'react' // Higher order component const withBorder = (Component, customStyle) => { class WithBorder extends React.Component { render() { const style = { border: this.props.customStyle ? this.props.customStyle.border : '3px solid teal' } return <Component style={style} {...this.props} /> } } return WithBorder } function MyComponent({ style, ...rest }) { return ( <p style={style} {...rest}> <h2> This is my component and I am expecting some styles. </h2> </p> ) } export default withBorder(MyComponent, { border: '4px solid teal' })
经过withBorder装饰的MyComponent组件, 就具备了统一border这项功能, 后面如果如果要做修改, 就可以在这个中间层
统一处理, 非常方便。
在我的项目里, 也用了一些高阶组件, 举个具体的例子:
PackEditor = withTranslate(PackEditor)
我们的这个 PackEditor
就是一个增强过的组件, 增加了什么功能呢?
正如名字表述的, withTranslate
, 增加了一个翻译功能, 下面也给大家看看这个组件是怎么实现的:
import React from 'react' import { Provider } from 'react-redux' import { injectIntl } from 'react-intl' import { store } from '@redux/store' import { Intl } from './Locale' const withTranslate = BaseComponent => (props) => { // avoid create a new component on re-render const IntlComponent = React.useMemo(() => injectIntl( ({ intl, ...others }) => ( <BaseComponent intl={intl} translate={(id, values = {}) => { // 注入翻译方法 if (!id) { return '' } return intl.formatMessage( typeof id === 'string' ? { id } : id, values ) }} {...others} /> ) ), []) IntlComponent.displayName = `withTranslate(${BaseComponent.displayName || 'BaseComponent'})` return ( <Provider store={store}> <Intl> <IntlComponent {...props} /> </Intl> </Provider> ) } export default withTranslate
用法很灵过:
const Editor = withTranslate(({ // ... translate, }) => { // ... return ( <> {translate('xxx')}} </> ) })
十分的方便。
4. Render props
Rrender prop 是指一种在 React 组件之间
使用一个值为函数的 prop 共享代码
的简单技术, 和 HOC 类似, 都是组件间的逻辑复用问题
。
更具体地说,Render prop 是一个用于告知组件需要渲染什么内容
的函数。
下面看一下简单的例子:
以下组件跟踪 Web 应用程序中的鼠标位置:
class Mouse extends React.Component { state = { x: 0, y: 0 }; handleMouseMove = (event) => { this.setState({ x: event.clientX, y: event.clientY }); } render() { return ( <p style={{ height: '100%' }} onMouseMove={this.handleMouseMove}> <p>The current mouse position is ({this.state.x}, {this.state.y})</p> </p> ); } } class MouseTracker extends React.Component { render() { return ( <> <h1>移动鼠标!</h1> <Mouse /> </> ); } }
当光标在屏幕上移动时,组件显示其(x,y)坐标。
现在的问题是:
我们如何在另一个组件中复用这个行为?
换个说法,若另一个组件需要知道鼠标位置,我们能否封装这一行为,以便轻松地与其他组件共享它 ??
假设产品想要这样一个功能: 在屏幕上呈现一张在屏幕上追逐鼠标的猫的图片。
我们或许会使用 巴适~ 简单粗暴, 一分钟完成任务。 可是,如果下次产品 以上的例子,虽然可以完成了猫追鼠标的需求,还没有达到以 当我们想要鼠标位置用于不同的用例时,我们必须创建一个新的组件,专门为该用例呈现一些东西. 这也是 render prop 的来历: 我们可以提供一个带有函数 prop 的 修改一下上面的代码: 提供了一个render 方法,让动态决定什么需要渲染。 事实上,render prop 是因为模式才被称为 render prop ,不一定要用名为 render 的 prop 来使用这种模式。 另外,关于 render prop 一个有趣的事情是你可以使用带有 render prop 的常规组件来实现大多数高阶组件 (HOC)。 例如,如果你更喜欢使用 withMouse HOC 而不是 <Mouse> 组件,你可以使用带有 render prop 的常规 <Mouse> 轻松创建一个: 也是非常的简洁清晰。 有一点需要注意的是, 如果你在定义的render函数里创建函数, 使用 render prop 会 因为浅比较 props 的时候总会得到 false,并且在这种情况下每一个 render 对于 render prop 将会生成 在这样例子中,每次 为了 5.组件性能 性能优化是永恒的主题, 这里不一一细说, 提供积分资源供你参考: 总结 以上几点都是我们经常要使用的技巧, 简单实用, 分享给大家, 希望能给大家带来一些帮助或启发,谢谢。 推荐阅读:React在线手册 Atas ialah kandungan terperinci 4个开发React应用的实用技巧. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!class Cat extends React.Component {
render() {
const mouse = this.props.mouse;
return (
<img src="/cat.jpg" style={{ position: 'absolute', left: mouse.x, top: mouse.y }} />
);
}
}</p>
<p>这个需求如此简单,你可能就直接修改Mouse组件了:</p>
<pre class="brush:php;toolbar:false">class Mouse extends React.Component {
state = { x: 0, y: 0 };
handleMouseMove = (event) => {
this.setState({
x: event.clientX,
y: event.clientY
});
}
render() {
return (
<p style={{ height: '100%' }} onMouseMove={this.handleMouseMove}>
<Cat mouse={this.state} />
</p>
);
}
}
再要想加条狗呢
?可复用的方式
真正封装行为的目标。<Mouse>
组件,它能够动态决定
什么需要渲染的,而不是将 硬编码
到 <Mouse> 组件里.class Cat extends React.Component {
render() {
const mouse = this.props.mouse;
return (
<img src="/cat.jpg" style={{ position: 'absolute', left: mouse.x, top: mouse.y }} />
);
}
}
class Mouse extends React.Component {
state = { x: 0, y: 0 };
handleMouseMove = (event) => {
this.setState({
x: event.clientX,
y: event.clientY
});
}
render() {
return (
<p style={{ height: '100%' }} onMouseMove={this.handleMouseMove}>
{this.props.render(this.state)}
</p>
);
}
}
class MouseTracker extends React.Component {
render() {
return (
<p>
<h1>移动鼠标!</h1>
<Mouse render={mouse => (
<Cat mouse={mouse} />
)}/>
</p>
);
}
}
任何被用于告知组件需要渲染什么内容的函数 prop, 在技术上都可以被称为 "render prop".
function withMouse(Component) {
return class extends React.Component {
render() {
return (
<Mouse render={mouse => (
<Component {...this.props} mouse={mouse} />
)}/>
);
}
}
}
抵消
使用 React.PureComponent 带来的优势。一个新的值
。class Mouse extends React.PureComponent {
// 与上面相同的代码......
}
class MouseTracker extends React.Component {
render() {
return (
<>
<Mouse render={mouse => ( // 这是不好的! 每个渲染的 `render` prop的值将会是不同的。
<Cat mouse={mouse} />
)}/>
</>
);
}
}
绕过这一问题
,有时你可以定义一个 prop 作为实例方法
,类似这样:class MouseTracker extends React.Component {
renderTheCat(mouse) {
return <Cat mouse={mouse} />;
}
render() {
return (
<p>
<h1>Move the mouse around!</h1>
<Mouse render={this.renderTheCat} />
</p>
);
}
}

Alat AI Hot

Undresser.AI Undress
Apl berkuasa AI untuk mencipta foto bogel yang realistik

AI Clothes Remover
Alat AI dalam talian untuk mengeluarkan pakaian daripada foto.

Undress AI Tool
Gambar buka pakaian secara percuma

Clothoff.io
Penyingkiran pakaian AI

AI Hentai Generator
Menjana ai hentai secara percuma.

Artikel Panas

Alat panas

Notepad++7.3.1
Editor kod yang mudah digunakan dan percuma

SublimeText3 versi Cina
Versi Cina, sangat mudah digunakan

Hantar Studio 13.0.1
Persekitaran pembangunan bersepadu PHP yang berkuasa

Dreamweaver CS6
Alat pembangunan web visual

SublimeText3 versi Mac
Perisian penyuntingan kod peringkat Tuhan (SublimeText3)

Topik panas



WebSocket dan JavaScript: Teknologi utama untuk merealisasikan sistem pemantauan masa nyata Pengenalan: Dengan perkembangan pesat teknologi Internet, sistem pemantauan masa nyata telah digunakan secara meluas dalam pelbagai bidang. Salah satu teknologi utama untuk mencapai pemantauan masa nyata ialah gabungan WebSocket dan JavaScript. Artikel ini akan memperkenalkan aplikasi WebSocket dan JavaScript dalam sistem pemantauan masa nyata, memberikan contoh kod dan menerangkan prinsip pelaksanaannya secara terperinci. 1. Teknologi WebSocket

JavaScript dan WebSocket: Membina sistem ramalan cuaca masa nyata yang cekap Pengenalan: Hari ini, ketepatan ramalan cuaca sangat penting kepada kehidupan harian dan membuat keputusan. Apabila teknologi berkembang, kami boleh menyediakan ramalan cuaca yang lebih tepat dan boleh dipercayai dengan mendapatkan data cuaca dalam masa nyata. Dalam artikel ini, kita akan mempelajari cara menggunakan teknologi JavaScript dan WebSocket untuk membina sistem ramalan cuaca masa nyata yang cekap. Artikel ini akan menunjukkan proses pelaksanaan melalui contoh kod tertentu. Kami

Tutorial JavaScript: Bagaimana untuk mendapatkan kod status HTTP, contoh kod khusus diperlukan: Dalam pembangunan web, interaksi data dengan pelayan sering terlibat. Apabila berkomunikasi dengan pelayan, kami selalunya perlu mendapatkan kod status HTTP yang dikembalikan untuk menentukan sama ada operasi itu berjaya dan melaksanakan pemprosesan yang sepadan berdasarkan kod status yang berbeza. Artikel ini akan mengajar anda cara menggunakan JavaScript untuk mendapatkan kod status HTTP dan menyediakan beberapa contoh kod praktikal. Menggunakan XMLHttpRequest

Pengenalan kepada kaedah mendapatkan kod status HTTP dalam JavaScript: Dalam pembangunan bahagian hadapan, kita selalunya perlu berurusan dengan interaksi dengan antara muka bahagian belakang, dan kod status HTTP adalah bahagian yang sangat penting daripadanya. Memahami dan mendapatkan kod status HTTP membantu kami mengendalikan data yang dikembalikan oleh antara muka dengan lebih baik. Artikel ini akan memperkenalkan cara menggunakan JavaScript untuk mendapatkan kod status HTTP dan memberikan contoh kod khusus. 1. Apakah kod status HTTP bermakna kod status HTTP apabila penyemak imbas memulakan permintaan kepada pelayan, perkhidmatan tersebut

Pengenalan kepada JS-Torch JS-Torch ialah perpustakaan JavaScript pembelajaran mendalam yang sintaksnya hampir sama dengan PyTorch. Ia mengandungi objek tensor berfungsi sepenuhnya (boleh digunakan dengan kecerunan yang dijejaki), lapisan dan fungsi pembelajaran mendalam, dan enjin pembezaan automatik. JS-Torch sesuai untuk penyelidikan pembelajaran mendalam dalam JavaScript dan menyediakan banyak alatan dan fungsi yang mudah untuk mempercepatkan pembangunan pembelajaran mendalam. Image PyTorch ialah rangka kerja pembelajaran mendalam sumber terbuka yang dibangunkan dan diselenggara oleh pasukan penyelidik Meta. Ia menyediakan set alat dan perpustakaan yang kaya untuk membina dan melatih model rangkaian saraf. PyTorch direka bentuk untuk menjadi ringkas, fleksibel dan mudah digunakan, dan ciri graf pengiraan dinamiknya menjadikan

Go dan Node.js mempunyai perbezaan dalam menaip (kuat/lemah), konkurensi (goroutine/gelung peristiwa) dan pengumpulan sampah (automatik/manual). Go mempunyai daya pemprosesan yang tinggi dan kependaman rendah, dan sesuai untuk bahagian belakang beban tinggi Node.js bagus pada I/O tak segerak dan sesuai untuk permintaan serentak tinggi dan pendek. Kes praktikal kedua-duanya termasuk Kubernetes (Go), sambungan pangkalan data (Node.js) dan aplikasi web (Go/Node.js). Pilihan terakhir bergantung pada keperluan aplikasi, kemahiran pasukan, dan keutamaan peribadi.

JavaScript dan WebSocket: Membina enjin carian masa nyata yang cekap Pengenalan: Dengan pembangunan Internet, pengguna mempunyai keperluan yang lebih tinggi dan lebih tinggi untuk enjin carian masa nyata. Apabila mencari dengan enjin carian tradisional, pengguna perlu mengklik butang carian untuk mendapatkan hasil kaedah ini tidak dapat memenuhi keperluan pengguna untuk hasil carian masa nyata. Oleh itu, menggunakan teknologi JavaScript dan WebSocket untuk melaksanakan enjin carian masa nyata telah menjadi topik hangat. Artikel ini akan memperkenalkan secara terperinci penggunaan JavaScript

Gambaran keseluruhan cara menggunakan WebSocket dan JavaScript untuk melaksanakan sistem tandatangan elektronik dalam talian: Dengan kemunculan era digital, tandatangan elektronik digunakan secara meluas dalam pelbagai industri untuk menggantikan tandatangan kertas tradisional. Sebagai protokol komunikasi dupleks penuh, WebSocket boleh melakukan penghantaran data dua hala masa nyata dengan pelayan Digabungkan dengan JavaScript, sistem tandatangan elektronik dalam talian boleh dilaksanakan. Artikel ini akan memperkenalkan cara menggunakan WebSocket dan JavaScript untuk membangunkan dalam talian yang mudah
