Kesalahan paling umum dalam kode Bereaksi yang Anda (mungkin) buat


Terinspirasi oleh artikel baca di media, saya memutuskan untuk menulis artikel saya dan memberitahu Anda bagaimana menghindari kesalahan paling umum dalam aplikasi Bereaksi Anda dan mengapa Anda perlu melakukan ini.


Semua kode ditulis dalam gaya ES6, jadi untuk mengulanginya Anda harus menggunakan Babel dalam proyek Anda (dan ada orang lain yang tidak menggunakannya?).


Saya mencoba menjelaskan setiap kesalahan sedetail mungkin, oleh karena itu, artikel saya lebih fokus pada pengembang muda yang masih mencari pengetahuan baru. Meskipun, menurut saya, pengembang yang berpengalaman dapat menemukan beberapa hal menarik untuk dirinya sendiri dalam artikel ini.


Jika Anda tertarik, selamat datang di kucing.


Dalam tanda kurung sebelum setiap paragraf, saya meninggalkan tautan ke aturan eslint. Anda nanti dapat menemukannya di git dan menambahkannya ke proyek Anda.



(bereaksi / melarang-komponen-alat peraga)


Kesalahan umum pertama adalah melewati 'style' dan 'className' sebagai alat peraga ke komponen Anda. Hindari ini karena Anda menambahkan banyak kerumitan pada komponen Anda.


Sebagai gantinya, Anda dapat menggunakan pustaka 'classnames' dan menambahkan variasi menarik ke komponen Anda (jika Anda menggunakan kelas css):


const { hasError, hasBorder } = this.props; const componentClasses = classnames({ 'your-component-main-class': true, 'your-component-main-class_with-error': hasError, 'your-component-main-class_with-border': hasBorder, }); 


(bereaksi / melarang-prop-type)


Kesalahan berikutnya bukan propTip informatif. Jangan gunakan PropTypes.any, PropTypes.array dan PropTypes.object. Jelaskan alat peraga Anda sedetail mungkin. Ini akan memungkinkan Anda untuk meninggalkan dokumentasi yang baik untuk masa depan, dan Anda (atau pengembang lain) akan berterima kasih berkali-kali.


 class MyComponent extends React.Component { static propTypes = { user: PropTypes.shape({ id: PropTypes.number, name: PropTypes.string, }), policies: PropTypes.arrayOf(PropTypes.shape({ id: PropTypes.number, type: PropTypes.string, value: PropTypes.string, }), } } 


(bereaksi / melarang-asing-prop-type)


Mari kita lanjutkan dengan propTip. Jangan gunakan propTip komponen lain:


 import SomeComponent from './SomeComponent'; SomeComponent.propTypes; 

Buat file di mana Anda akan menjaga propTypes global Anda agar:


 import { userShape, policiesArray } from '../common/global_prop_types'; 

Ini akan membantu babel-plugin-transform-react-remove-prop-types menghapus propTypes dari kode produksi dan membuat aplikasi Anda sedikit lebih mudah.



(bereaksi / tidak-akses-status-in-setstate)


Kesalahan berikut ini sangat menarik:


 class MyComponent extends React.Component { state = { counter: 1, }; incrementCounter = () => this.setState({ counter: this.state.counter + 1 }); massIncrement = () => { // this code will lead to not what you expect this.incrementCounter(); this.incrementCounter(); } } 

Karena setState adalah fungsi status asinkron keadaan dalam kedua kasus akan sama.
this.state.counter akan menjadi 1 dan kita akan mendapatkan:


 incrementCounter = () => this.setState({ counter: 1 + 1 }); incrementCounter = () => this.setState({ counter: 1 + 1 }); 

Untuk menghindarinya, Anda bisa menggunakan setState callback yang menerima status negara sebagai argumen:


 incrementCounter = () => this.setState((prevState) => ({ counter: prevState.counter + 1 })); 


(bereaksi / tidak-larik-indeks-kunci)


Kesalahan ini juga sangat umum, oleh karena itu, baca dengan cermat dan hindarilah di masa mendatang:


 users.map((user, index) => ( <UserComponent {...user} key={index} /> )); 

Bereaksi menggunakan kunci prop sebagai tautan ke elemen DOM, dan ini membantunya dengan cepat menemukan dan merender komponen yang diperlukan (semuanya, tentu saja, lebih rumit, tapi saya sengaja menyederhanakannya dengan sengaja).
Apa yang terjadi jika Anda menambahkan pengguna baru di tengah array? Bereaksi akan dipaksa untuk me-render ulang semua komponen UserComponents setelah yang baru ditambahkan, karena indeks akan diubah untuk sejumlah besar komponen. Gunakan kunci unik saja. Jalan keluar yang sangat sederhana adalah id yang Anda dapatkan dari database Anda:


 users.map((user) => ( <UserComponent {...user} key={user.id} /> )); 


(reaksi / no-did-mount-set-state), (reaksi / no-do-update-set-state)


Kesalahan ini juga sangat umum dalam latihan saya. Jika Anda mencoba memperbarui status dalam metode componentDidUpdate, Anda mendapatkan loop re-render yang tak terbatas. React memulai pemeriksaan untuk rendering ulang ketika komponen berubah status atau properti. Jika Anda mengubah status setelah komponen dipasang di DOM atau telah diperbarui, Anda akan menjalankan pemeriksaan lagi dan lagi dan lagi ...
Saat memperbarui keadaan di componentDidMount, Anda dapat memanggil komponen yang di-render sekali lagi, karena fungsinya dipanggil sekali setelah komponen dipasang di DOM.
Jika Anda perlu memperbarui data setelah memasang komponen, saya sarankan menggunakan variabel kelas:


 class MyComponent extends React.Component { componentDidMount() { this.veryImportantDataThatCanBeStoredOnlyAfterMount = 'I'll be back!'; } veryImportantDataThatCanBeStoredOnlyAfterMount = void 0; render() { return <div /> } } 


(bereaksi / tidak-langsung-mutasi-negara)


Mutasi negara adalah kesalahan yang sangat besar. Mutasi status yang tidak terkendali akan menyebabkan bug tidak terdeteksi dan, sebagai akibatnya, menjadi masalah besar. Pendapat pribadi saya adalah penggunaan immsable-js , sebagai perpustakaan yang menambahkan struktur abadi. Dan Anda dapat menggunakannya dengan Redux / MobX / Setiap perpustakaan manajemen negara. Anda juga dapat menggunakan deepClone dari lodash to clone state dan kemudian memutasi clone, atau menggunakan fitur JS baru - merusak:


 updateStateWrong = () => this.state.imRambo = true; updateStateRight = () => { const clonedState = cloneDeep(this.state); clonedState.imAGoodMan = true; this.setState(clonedState); } updateWithImmutabelJS = () => { const newState = this.state.data.set('iUseImmutableStructure', true); this.setState(data: newState); } updateWithDestructuring = () => this.setState({ ...this.state, iUseDestructuring: true }); 


(bereaksi / prefer-stateless-function)


Aturan ini menjelaskan lebih banyak perbaikan kode dan aplikasi Anda daripada kesalahan, tetapi saya tetap menyarankan Anda mengikuti aturan ini. Jika komponen Anda tidak menggunakan status, jadikan ini komponen tanpa kewarganegaraan (Saya lebih suka istilah 'komponen murni'):


 class MyComponentWithoutState extends React.Component { render() { return <div>I like to write a lot of unneeded code</div> } } const MyPureComponent = (props) => <div>Less code === less support</div> 


(bereaksi / prop-type)


Harap selalu tambahkan memeriksa jenis alat peraga (propTypes) jika komponen Anda menerima alat peraga. Anggap saja mendokumentasikan kode Anda. Lebih dari sekali Anda akan mengatakan pada diri sendiri 'terima kasih' untuk ini (dan mungkin untuk saya :)). PropTypes akan membantu Anda memahami dan memahami apa yang komponen Anda dapat render, serta apa yang dibutuhkan untuk rendering.


 MyPureComponent.propTypes = { id: PropTypes.number.isRequired, // And I know that without id component will not render at all, and this is good. } 


(bereaksi / jsx-no-bind)


Kesalahan yang sangat umum dan besar yang saya lihat dalam kode berkali-kali. Jangan Menggunakan Fungsi Bind Dan Arrow Di Jsx. Tidak pernah. Lebih banyak.
Tempat terpanas di neraka menunggu orang yang menulis .bind (ini) di JSX di event handler.
Setiap kali komponen dirender, fungsi Anda akan dibuat kembali, dan ini dapat sangat memperlambat aplikasi Anda (ini disebabkan oleh fakta bahwa pengumpul sampah akan dipaksa untuk menjalankan lebih sering). Alih-alih .bind (ini), Anda dapat menggunakan fungsi Panah dengan cara tertentu:


 class RightWayToCallFunctionsInRender extends React.Component { handleDivClick = (event) => event; render() { return <div onClick={this.handleDivClick} /> } } const handleDivClick = (event) => event; const AndInPureComponent = () => { return <div onClick={handleDivClick} /> } 


(bereaksi / jsx-no-target-blank)


Bug keamanan. Rasanya sangat aneh bagi saya bahwa orang masih membuat kesalahan ini. Banyak orang menulis banyak artikel tentang topik ini pada tahun 2017.
Jika Anda membuat tautan dengan atribut target = '_ blank', pastikan untuk menambahkan rel = 'noreferrer noopener' ke sana. Sangat sederhana:


 <a href="https://example.com" target="_blank" rel="noreferrer noopener" /> 

Terima kasih


Hanya itu yang ingin saya sampaikan kepada Anda sebagai bagian dari artikel ini. Saya akan sangat berterima kasih jika Anda, pembaca saya, meninggalkan saya umpan balik atau komentar Anda dan membagikan pendapat Anda tentang masalah yang saya jelaskan di artikel ini. Juga, Anda dapat memberi tahu saya tentang kesalahan saya dan Anda dalam kode dan tentang segala sesuatu yang Anda anggap perlu untuk diceritakan. Terima kasih lagi!

Source: https://habr.com/ru/post/id416511/


All Articles