Pendekatan yang sebagian besar reasonable untuk React dan JSX
Panduan style guide ini sebagian besar didasarkan pada standar yang saat ini lazim di Javascript, meskipun beberapa konvensi (yaitu async/await atau static class fields) masih bisa dimasukkan atau dilarang berdasarkan kasus per kasus. Saat ini, apapun sebelum tahap ke 3 tidak termasuk atau direkomendasikan dalam panduan ini.
- Aturan Dasar
- Class vs
React.createClassvs stateless - Mixins
- Penamaan
- Deklarasi
- Alignment
- Quotes
- Spacing
- Props
- Refs
- Tanda Kurung
- Tags
- Methods
- Ordering
isMounted
- Hanya menyertakan satu React component per file.
- Namun, multiple Stateless, atau Pure, Components diizinkan per file. eslint:
react/no-multi-comp.
- Namun, multiple Stateless, atau Pure, Components diizinkan per file. eslint:
- Selalu gunakan sintaks JSX.
- Jangan gunakan
React.createElementkecuali Anda menginisialisasi aplikasi dari file yang bukan JSX. react/forbid-prop-typesakan memperbolehkanarraysdanobjectshanya jika secara ekplisit ditulis dengan isiarraydanobject, menggunakanarrayOf,objectOf, ataushape.
-
Jika Anda memiliki internal state dan/atau refs, lebih baik gunakan
class extends React.ComponentdaripadaReact.createClass. eslint:react/prefer-es6-classreact/prefer-stateless-function// buruk const Listing = React.createClass({ // ... render() { return <div>{this.state.hello}</div>; } }); // baik class Listing extends React.Component { // ... render() { return <div>{this.state.hello}</div>; } }
Dan jika Anda tidak memiliki state atau refs, lebih baik gunakan fungsi biasa (bukan arrow functions) daripada classes:
// buruk class Listing extends React.Component { render() { return <div>{this.props.hello}</div>; } } // buruk (mengandalkan inferensi nama fungsi yang tidak disarankan) const Listing = ({ hello }) => ( <div>{hello}</div> ); // baik function Listing({ hello }) { return <div>{hello}</div>; }
Mengapa? Mixins memperkenalkan dependensi yang implisit, menyebabkan nama tidak sesuai, dan kompleksitas snowballing. Sebagian besar kasus untuk mixins dapat diselesaikan dengan cara yang lebih baik melalui components, higher-order components, atau utility modules.
-
Ekstensi: Gunakan ekstensi
.jsxuntuk React components. eslint:react/jsx-filename-extension -
Nama file: Gunanakan PascalCase untuk nama file. Contoh:
ReservationCard.jsx. -
Penamaan Referensi: Gunakan PascalCase untuk React components dan camelCase untuk intances nya. eslint:
react/jsx-pascal-case// buruk import reservationCard from './ReservationCard'; // baik import ReservationCard from './ReservationCard'; // buruk const ReservationItem = <ReservationCard />; // baik const reservationItem = <ReservationCard />;
-
Penamaan Komponen: Gunakan nama file sebagai nama komponen. Sebagai contoh,
ReservationCard.jsxharus memiliki nama referensi dariReservationCard. Namun, untuk komponen root dari direktori, menggunakanindex.jsxsebagai nama file dan gunakan nama direktori sebagai nama komponen:// buruk import Footer from './Footer/Footer'; // buruk import Footer from './Footer/index'; // baik import Footer from './Footer';
-
Penamaan Higher-order Component: Gunakan sebuah komposit dari nama higher-order component dan nama komponen yang diteruskan sebagai
displayNamepada komponen yang dihasilkan. Sebagai contoh,withFoo()pada higher-order component , ketika melewati komponenBarharus menghasilkan komponen dengandisplayNamedariwithFoo(Bar).Mengapa?
displayNamedapat digunakan oleh developer tools atau dalam pesan error, dan memiliki nilai yang secara jelas mengungkapkan hubungan untuk membantu orang memahami apa yang terjadi.// buruk export default function withFoo(WrappedComponent) { return function WithFoo(props) { return <WrappedComponent {...props} foo />; } } // baik export default function withFoo(WrappedComponent) { function WithFoo(props) { return <WrappedComponent {...props} foo />; } const wrappedComponentName = WrappedComponent.displayName || WrappedComponent.name || 'Component'; WithFoo.displayName = `withFoo(${wrappedComponentName})`; return WithFoo; }
-
Penamaan Props: Hindari penggunaan nama prop pada komponen DOM untuk tujuan yang berbeda.
Mengapa? Orang akan berpikir props seperti
styledanclassNameberarti satu hal tertentu. Memvariasikan API ini untuk sebagian dari aplikasi Anda sehingga membuat kode lebih mudah dibaca dan kurang terpelihara, dan dapat menyebabkan bug.// buruk <MyComponent style="fancy" /> // buruk <MyComponent className="fancy" /> // baik <MyComponent variant="fancy" />
-
Jangan gunakan
displayNameuntuk penamaai sebuah komponen. Sebagai gantinya, beri nama pada komponen dengan referensi.// buruk export default React.createClass({ displayName: 'ReservationCard', // stuff goes here }); // baik export default class ReservationCard extends React.Component { }
-
Ikuti alignment styles ini untuk sintaks JSX. eslint:
react/jsx-closing-bracket-locationreact/jsx-closing-tag-location// buruk <Foo superLongParam="bar" anotherSuperLongParam="baz" /> // baik <Foo superLongParam="bar" anotherSuperLongParam="baz" /> // jika properti dimuat dalam satu baris maka tetap pada satu baris yang sama <Foo bar="bar" /> // children mendapatkan indentasi secara normal <Foo superLongParam="bar" anotherSuperLongParam="baz" > <Quux /> </Foo> // buruk {showButton && <Button /> } // buruk { showButton && <Button /> } // baik {showButton && ( <Button /> )} // baik {showButton && <Button />}
-
Selalu gunakan tanda kutip ganda (
") untuk atribut JSX, tetapi tanda kutip tunggal (') untuk semua JS lainnya. eslint:jsx-quotesMengapa? Atribut HTML juga biasanya menggunakan tanda kutip ganda bukan tunggal, jadi atribut JSX menggunakan ketentuan ini.
// buruk <Foo bar='bar' /> // baik <Foo bar="bar" /> // buruk <Foo style={{ left: "20px" }} /> // baik <Foo style={{ left: '20px' }} />
-
Selalu sisipkan satu spasi di tag self-closing. eslint:
no-multi-spaces,react/jsx-tag-spacing// buruk <Foo/> // sangat buruk <Foo /> // buruk <Foo /> // baik <Foo />
-
Jangan menyisipkan spasi didalam kurung kurawal JSX. eslint:
react/jsx-curly-spacing// buruk <Foo bar={ baz } /> // baik <Foo bar={baz} />
-
Selalu gunakan camelCase untuk nama prop.
// buruk <Foo UserName="hello" phone_number={12345678} /> // baik <Foo userName="hello" phoneNumber={12345678} />
-
Hilangkan nama prop jika itu secara ekplisit bernilai
true. eslint:react/jsx-boolean-value// buruk <Foo hidden={true} /> // baik <Foo hidden /> // baik <Foo hidden />
-
Selalu sertakan
altprop pada setiap tag<img>. Jika gambar adalah presentational,altdapat berisi string kosong atau<img>harus memilikirole="presentation". eslint:jsx-a11y/alt-text// buruk <img src="hello.jpg" /> // baik <img src="hello.jpg" alt="Me waving hello" /> // baik <img src="hello.jpg" alt="" /> // baik <img src="hello.jpg" role="presentation" />
-
Jangan gunakan kata-kata seperti "image", "photo", atau "picture" di
<img>altprops. eslint:jsx-a11y/img-redundant-altMengapa? Screenreaders sudah memberitahu elemen
imgsebagai gambar, jadi tidak perlu memberikan informasi ini didalam alt.// buruk <img src="hello.jpg" alt="Picture of me waving hello" /> // baik <img src="hello.jpg" alt="Me waving hello" />
-
Gunakan yang sesuai, non-abstract ARIA roles. eslint:
jsx-a11y/aria-role// buruk - not an ARIA role <div role="datepicker" /> // buruk - abstract ARIA role <div role="range" /> // baik <div role="button" />
-
Jangan gunakan
accessKeypada elemen. eslint:jsx-a11y/no-access-key
Mengapa? Ketidakkonsistenan antara keyboard shortcuts dan keyboard commands yang digunakan oleh seseorang yang menggunakan screenreaders dan keyboards mempersulit aksesbilitas.
// buruk
<div accessKey="h" />
// baik
<div />- Hindari menggunakan indeks array sebagai
keypada prop, disarankan menggunakan ID yang lebih stabil. eslint:react/no-array-index-key
Mengapa? Tidak menggunakan ID adalah anti-pattern karena dapat berdampak negatif pada kinerja dan menyebabkan masalah pada component state.
Kami tidak merekomendasikan untuk menggunakan indeks sebagai keys jika urutan item dapat berubah.
// buruk
{todos.map((todo, index) =>
<Todo
{...todo}
key={index}
/>
)}
// baik
{todos.map(todo => (
<Todo
{...todo}
key={todo.id}
/>
))}- Selalu definisikan defaultProps secara ekplisit untuk semua prop yang tidak diperlukan.
Mengapa? propTypes adalah bentuk dokumentasi, dan menyediakan defaultProps yang berarti pembaca kode Anda tidak perlu berasumsi sebanyak itu.
// buruk
function SFC({ foo, bar, children }) {
return <div>{foo}{bar}{children}</div>;
}
SFC.propTypes = {
foo: PropTypes.number.isRequired,
bar: PropTypes.string,
children: PropTypes.node,
};
// baik
function SFC({ foo, bar, children }) {
return <div>{foo}{bar}{children}</div>;
}
SFC.propTypes = {
foo: PropTypes.number.isRequired,
bar: PropTypes.string,
children: PropTypes.node,
};
SFC.defaultProps = {
bar: '',
children: null,
};- Gunakan spread prop dengan hemat (sparingly).
Mengapa? kalau tidak, Anda akan lebih cenderung meneruskan properti yang tidak perlu ke komponen. Dan untuk React v15.6.1 keatas, Anda dapat mem-passing atribut HTML yang tidak valid ke DOM.
Pengecualian:
- HOCs that proxy down props dan hoist propTypes
function HOC(WrappedComponent) {
return class Proxy extends React.Component {
Proxy.propTypes = {
text: PropTypes.string,
isLoading: PropTypes.bool
};
render() {
return <WrappedComponent {...this.props} />
}
}
}- Spreading dengan objek yang dikenal, explicit props. Ini bisa sangat bergunakan ketika men-testing komponen React dengan Mocha's beforeEach construct.
export default function Foo {
const props = {
text: '',
isPublished: false
}
return (<div {...props} />);
}Catatan untuk digunakan: Filter prop yang tidak diperlukan jika memungkinkan. Selain itu, gunakan prop-types-exact untuk membantu mencegah bug.
// buruk
render() {
const { irrelevantProp, ...relevantProps } = this.props;
return <WrappedComponent {...this.props} />
}
// baik
render() {
const { irrelevantProp, ...relevantProps } = this.props;
return <WrappedComponent {...relevantProps} />
}-
Selalu gunakan ref callbacks. eslint:
react/no-string-refs// buruk <Foo ref="myRef" /> // baik <Foo ref={(ref) => { this.myRef = ref; }} />
-
Bungkus tag JSX dengan tanda kurung ketika lebih dari satu baris. eslint:
react/jsx-wrap-multilines// buruk render() { return <MyComponent variant="long body" foo="bar"> <MyChild /> </MyComponent>; } // baik render() { return ( <MyComponent variant="long body" foo="bar"> <MyChild /> </MyComponent> ); } // baik, ketika statement hanya 1 baris render() { const body = <div>hello</div>; return <MyComponent>{body}</MyComponent>; }
-
Selalu self-close tags yang tidak memiliki children. eslint:
react/self-closing-comp// buruk <Foo variant="stuff"></Foo> // baik <Foo variant="stuff" />
-
Jika komponen Anda memilki properti yang multi-line, tutup tag-nya di baris baru. eslint:
react/jsx-closing-bracket-location// buruk <Foo bar="bar" baz="baz" /> // baik <Foo bar="bar" baz="baz" />
-
Gunakan arrow functions untuk menutup variabel lokal. Ini berguna ketika Anda memberikan data tambahan ke event handler. Meskipun, pastikan mereka tidak secara masiv merusak peforma, khususnya ketika mem-passing ke komponen kustom yang mungkin meruapakan PureComponents, karena mereka akan men-trigger rerender yang mungkin tidak setiap waktu.
function ItemList(props) { return ( <ul> {props.items.map((item, index) => ( <Item key={item.key} onClick={(event) => { doSomethingWith(event, item.name, index); }} /> ))} </ul> ); }
-
Bind event handlers untuk render method di constructor. eslint:
react/jsx-no-bindMengapa? sebuah bind call di render path membuat fungsi baru disetiap single render. Jangan gunakan arrow functions di class fields, karena itu membuat mereka challenging untuk test dan men-debug, dan dapat berdampak negatif pada performance, dan karena konseptual, class fields adalah untuk data. bukan logika.
// buruk class extends React.Component { onClickDiv() { // lakukan stuff } render() { return <div onClick={this.onClickDiv.bind(this)} />; } } // sangat buruk class extends React.Component { onClickDiv = () => { // lakukan stuff } render() { return <div onClick={this.onClickDiv} /> } } // baik class extends React.Component { constructor(props) { super(props); this.onClickDiv = this.onClickDiv.bind(this); } onClickDiv() { // do stuff } render() { return <div onClick={this.onClickDiv} />; } }
-
Jangan gunakan awalan (prefix) untuk internal methods komponen pada React.
Mengapa? Awalan garis bawah terkadang digunakan sebagai convention dalam bahasa lain untuk menunjukan private. Tapi, tidak seperti bahasa-bahasa itu, tidak ada dukungan asli untuk private di JavaScipt, semuanya bersifat public. Terlepas dari niat Anda, menambahkan awalan garis bawah ke properti Anda sebenarnya tidak menjadikan bersifat private, dan properti apapun (underscore-prefixed atau bukan) harus diperlakukan secara public. Lihat issues #1024, dan #490 untuk diskusi yang lebih mendalam.
// buruk React.createClass({ _onClickSubmit() { // lakukan stuff }, // stuff lain }); // baik class extends React.Component { onClickSubmit() { // lakukan stuff } // stuff lain }
-
Pastikan untuk mengembalikan nilai dalam method render
renderAnda. eslint:react/require-render-return// buruk render() { (<div />); } // baik render() { return (<div />); }
- Ordering for
class extends React.Component:
- metode
staticopsional constructorgetChildContextcomponentWillMountcomponentDidMountcomponentWillReceivePropsshouldComponentUpdatecomponentWillUpdatecomponentDidUpdatecomponentWillUnmount- clickHandlers atau eventHandlers seperti
onClickSubmit()atauonChangeDescription() - getter methods untuk
rendersepertigetSelectReason()ataugetFooterContent() - optional render methods seperti
renderNavigation()ataurenderProfilePicture() render
-
How to define
propTypes,defaultProps,contextTypes, etc...import React from 'react'; import PropTypes from 'prop-types'; const propTypes = { id: PropTypes.number.isRequired, url: PropTypes.string.isRequired, text: PropTypes.string, }; const defaultProps = { text: 'Hello World', }; class Link extends React.Component { static methodsAreOk() { return true; } render() { return <a href={this.props.url} data-id={this.props.id}>{this.props.text}</a>; } } Link.propTypes = propTypes; Link.defaultProps = defaultProps; export default Link;
-
Ordering untuk
React.createClass: eslint:react/sort-comp
displayNamepropTypescontextTypeschildContextTypesmixinsstaticsdefaultPropsgetDefaultPropsgetInitialStategetChildContextcomponentWillMountcomponentDidMountcomponentWillReceivePropsshouldComponentUpdatecomponentWillUpdatecomponentDidUpdatecomponentWillUnmount- clickHandlers or eventHandlers seperti
onClickSubmit()atauonChangeDescription() - getter methods for
rendersepertigetSelectReason()ataugetFooterContent() - optional render methods seperti
renderNavigation()ataurenderProfilePicture() render
- Jangan gunakan
isMounted. eslint:react/no-is-mounted
Mengapa?
isMountedis an anti-pattern, tidak tersedia saat menggunakan ES6 classes, dan sedang dalam perjalanan untuk secara resmi ditinggalkan.
Panduan JSX/React style ini juga tersedia dalam bahasa lain:
Chinese (Simplified): JasonBoy/javascript
Chinese (Traditional): jigsawye/javascript
Español: agrcrobles/javascript
Japanese: mitsuruog/javascript-style-guide
Korean: apple77y/javascript
Polish: pietraszekl/javascript
Portuguese: ronal2do/javascript
Russian: leonidlebedev/javascript-airbnb
Thai: lvarayut/javascript-style-guide
Turkish: alioguzhan/react-style-guide
Ukrainian: ivanzusko/javascript
Vietnam: uetcodecamp/jsx-style-guide