(Turkish Translation of Airbnb React/JSX Style Guide
React and JSX konularına oldukça makul bir yaklaşım
- Temel Kurallar
- Class vs
React.createClass
vs stateless - Mixinler
- Isimlendirme
- Deklarasyon
- Hizalama
- Tırnaklar
- Boşluk Kullanımı
- Proplar
- Refler
- Parantezler
- Taglar
- Metodlar
- Sıralama
isMounted
- Her bir dosyada sadece bir adet React Componenti barındırın.
- Ama, birden fazla Stateless ya da Pure Components aynı dosyada kullanılabilir. eslint:
react/no-multi-comp
.
- Ama, birden fazla Stateless ya da Pure Components aynı dosyada kullanılabilir. eslint:
- Daima JSX i kullanın.
- Uygulamayı JSX olmayan bir dosyadan başlatmadığınız sürece
React.createElement
i kullanmayın.
-
Eğer dahili olarak state ve / veya ref ler varsa,
React.createClass
yerineclass extends React.Component
kullanmayı tercih edin. eslint:react/prefer-es6-class
react/prefer-stateless-function
// kötü const Listing = React.createClass({ // ... render() { return <div>{this.state.hello}</div>; } }); // iyi class Listing extends React.Component { // ... render() { return <div>{this.state.hello}</div>; } }
Ve eğer state ya da ref leriniz yoksa, class lar içinde normal fonksiyonları (arrow fonksiyonları değil) tercih edin:
// kötü class Listing extends React.Component { render() { return <div>{this.props.hello}</div>; } } // kötü (Fonksiyon ismi çıkarımına güvenmek cesaret kırıcıdır.) const Listing = ({ hello }) => ( <div>{hello}</div> ); // iyi function Listing({ hello }) { return <div>{hello}</div>; }
Niye? Mixinler örtülü bağımlılıkları ortaya çıkarır, isim çatışmalarına neden olur ve snowballing karmaşıklığına neden olur. Mixinlerin kullanılmak istendiği bir çok durum, bileşenleri, daha üst düzey bileşenleri veya yardımcı modülleri kullanarak daha iyi yollarla başarılabilir.
-
Dosya Uzantıları: React Bileşenleri için
.jsx
uzantısını kullanın. -
Dosya İsimleri: Dosya isimleri için PascalCase yöntemini kullanın. Mesela,
ReservationCard.jsx
. -
Reference İsimlendirmesi: React Bileşenleri için PascalCase ve onların örnekleri için camelCase yöntemini kullanın. eslint:
react/jsx-pascal-case
// kötü import reservationCard from './ReservationCard'; // iyi import ReservationCard from './ReservationCard'; // kötü const ReservationItem = <ReservationCard />; // iyi const reservationItem = <ReservationCard />;
-
Bileşen İsimlendirmesi: Bileşen ismi olarak dosya adını kullanın. Örneğin,
ReservationCard.jsx
dosyasıReservationCard
adında bir bileşeni içermelidir. Ancak, bir klasörün kök bileşeni için; dosya ismi olarakindex.jsx
ve bileşen ismi olarak da klasörün ismini kullanın:// kötü import Footer from './Footer/Footer'; // iyi import Footer from './Footer/index'; // iyi import Footer from './Footer';
-
Üst-Sıralı Bileşen İsimlendirmesi: Oluşturulan bileşen üzerinde
displayName
olarak Üst-Sıralı Bileşen ismi ve aktarılan bileşenin isminden oluşan bir karma isim kullanın. Örneğin, Üst-Sıralı bileşen üyesi olanWithFoo ()
öğesi,Bar
adındakı bir bileşen tarafından iletildiğinde,displayName
iwithFoo(Bar)
olan bir bileşen üretmelidir.Neden? Bir Bileşenin
displayName
i, geliştirici araçlarında veya hata mesajlarında kullanılabilir; ve bu ilişkiyi açıkça ifade eden bir değere sahip olması, insanların neler olduğunu anlamasına yardımcı olur.// kötü export default function withFoo(WrappedComponent) { return function WithFoo(props) { return <WrappedComponent {...props} foo />; } } // iyi 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; }
-
Propların İsimlendirmesi: DOM Bileşenlerine ait isimleri başka amaçlar için kullanmaktan kaçının.
Neden? İnsanlar
style
veclassName
gibi proplarin tek belirgin bir anlama gelmesini bekler. Bu API yi uygulamanızın bir alt kümesi için değiştirmek kodu daha az okunabilir ve daha az sürdürülebilir hale getirir, ve buglara sebep olabilir.// kötü <MyComponent style="fancy" /> // iyi <MyComponent variant="fancy" />
-
Bileşenleri isimlendirmek için
displayName
kullanmayın. Onun yerine bileşeni referansa göre isimlendirin.// kötü export default React.createClass({ displayName: 'ReservationCard', // stuff goes here }); // iyi export default class ReservationCard extends React.Component { }
-
JSX sözdizimi için bu hizalama stillerini takip edin:
react/jsx-closing-bracket-location
react/jsx-closing-tag-location
// kötü <Foo superLongParam="bar" anotherSuperLongParam="baz" /> // iyi <Foo superLongParam="bar" anotherSuperLongParam="baz" /> // Eğer proplar bir satıra sığıyorsa aynı satırda tutun. <Foo bar="bar" /> // çocuklar normal olarak hizalanır. <Foo superLongParam="bar" anotherSuperLongParam="baz" > <Quux /> </Foo>
-
JSX nitelikleri için daima çift tırnak (
"
), ama diğer bütün JS için tek tırnak ('
) kullanın. eslint:jsx-quotes
Neden? Normal HTML nitelikleri de tek tırnak yerine çift tırnak kullanır, JSX nitelikleri de bu düzeni yansıtır.
// kötü <Foo bar='bar' /> // iyi <Foo bar="bar" /> // kötü <Foo style={{ left: "20px" }} /> // iyi <Foo style={{ left: '20px' }} />
-
Kendi kendine kapanan taglar için daima tek boşluk kullanın. eslint:
no-multi-spaces
,react/jsx-tag-spacing
// kötü <Foo/> // çok kötü <Foo /> // kötü <Foo /> // good <Foo />
-
JSX süslü parantezlerini boşlukla şişirmeyin. eslint:
react/jsx-curly-spacing
// kötü <Foo bar={ baz } /> // iyi <Foo bar={baz} />
-
Prop isimleri için daima camelCase kullanın.
// kötü <Foo UserName="hello" phone_number={12345678} /> // iyi <Foo userName="hello" phoneNumber={12345678} />
-
Açıkça
true
olarak belirtildiyse propun değerini atlayın. eslint:react/jsx-boolean-value
// kötü <Foo hidden={true} /> // iyi <Foo hidden /> // iyi <Foo hidden />
-
<img>
etiketlerine daima biralt
özelliği ekleyin. Eğer resim sunumsal ise,alt
boş bir dize olabilir veya<img>
etiketinde<role="presentation"
bulunmalıdır. eslint:jsx-a11y/alt-text
// kötü <img src="hello.jpg" /> // iyi <img src="hello.jpg" alt="Me waving hello" /> // iyi <img src="hello.jpg" alt="" /> // iyi <img src="hello.jpg" role="presentation" />
-
<img>
etiketininalt
özelliğinde "image", "photo", ya da "picture" gibi kelimeler kullanmayın. eslint:jsx-a11y/img-redundant-alt
Neden? Ekran okuyucuları zaten
img
elemanlarını resim olarak bildirdikleri için bu bilgiyi alt metne eklemenize gerek yoktur.// kötü <img src="hello.jpg" alt="Picture of me waving hello" /> // iyi <img src="hello.jpg" alt="Me waving hello" />
-
Yalnızca geçerli, soyut olmayan ARIA roles kullanın. eslint:
jsx-a11y/aria-role
// kötü - bir ARIA role değil <div role="datepicker" /> // kötü - soyut ARIA role <div role="range" /> // iyi <div role="button" />
-
Elemanlarde
accessKey
kullanmayın. eslint:jsx-a11y/no-access-key
Neden? Ekran okuyucu kullanan insanlar tarafından kullanılan klavye komutları ve klavye kısayolları ile klavyeler arasındaki tutarsızlıkar erişilebilirliği zorlaştırmaktadır.
// bad
<div accessKey="h" />
// good
<div />
key
özelliği için dizinin index değerini kullanmaktan kaçının; benzersiz bir ID tercih edin. (why?)
// kötü
{todos.map((todo, index) =>
<Todo
{...todo}
key={index}
/>
)}
// iyi
{todos.map(todo => (
<Todo
{...todo}
key={todo.id}
/>
))}
- Always define explicit defaultProps for all non-required props.
Why? propTypes are a form of documentation, and providing defaultProps means the reader of your code doesn’t have to assume as much. In addition, it can mean that your code can omit certain type checks.
// bad
function SFC({ foo, bar, children }) {
return <div>{foo}{bar}{children}</div>;
}
SFC.propTypes = {
foo: PropTypes.number.isRequired,
bar: PropTypes.string,
children: PropTypes.node,
};
// good
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,
};
-
ref değeri için her zaman callback kullanın. eslint:
react/no-string-refs
// kötü <Foo ref="myRef" /> // iyi <Foo ref={(ref) => { this.myRef = ref; }} />
-
JSX etiketleri bir satırdan fazla olursa parantezler kullanın. eslint:
react/jsx-wrap-multilines
// kötü render() { return <MyComponent className="long body" foo="bar"> <MyChild /> </MyComponent>; } // iyi render() { return ( <MyComponent className="long body" foo="bar"> <MyChild /> </MyComponent> ); } // iyi, eğer tek satırsa render() { const body = <div>hello</div>; return <MyComponent>{body}</MyComponent>; }
-
Hiçbir çocuğu olmayan etiketleri her zaman kendi kendine kapatın. eslint:
react/self-closing-comp
// kötü <Foo className="stuff"></Foo> // iyi <Foo className="stuff" />
-
Eğer bileşeninizin birden çok satırdan oluşan özellikleri varsa, bileşeni yeni bir satırda kapatın. eslint:
react/jsx-closing-bracket-location
// kötü <Foo bar="bar" baz="baz" /> // iyi <Foo bar="bar" baz="baz" />
-
Yerel değişkenleri kapatmak için ok fonksiyonları kullanın.
function ItemList(props) { return ( <ul> {props.items.map((item, index) => ( <Item key={item.key} onClick={() => doSomethingWith(item.name, index)} /> ))} </ul> ); }
-
Render metodunda kullanılacak olay yöneticilerini constructor metodunda bağlayın. eslint:
react/jsx-no-bind
Neden? Render metodunda yer alan bir bağlama çağrısı her render işleminde tamamen yeni bir fonksiyon yaratır.
// kötü class extends React.Component { onClickDiv() { // bişeyler yap } render() { return <div onClick={this.onClickDiv.bind(this)} />; } } // iyi class extends React.Component { constructor(props) { super(props); this.onClickDiv = this.onClickDiv.bind(this); } onClickDiv() { // bişeyler yap } render() { return <div onClick={this.onClickDiv} />; } }
-
React bileşeninin dahili metodları için alt çizgi önekini kullanmayın.
Neden? Alt çizgi önekleri gizliliği belirtmek için diğer dillerde bir kural olarak bazen kullanılır. Fakat, bu dillerin aksine, JavaScript'de gizlilik için doğal bir destek yok, her şey açıktır. Niyetlerinize bakılmaksızın, property lere alt çizgi önekleri eklemek onları aslında gizli kılmaz ve herhangi bir property (alt çizgi öneki içeren veya içermeyen) herkese açık olarak değerlendirilmelidir. Daha detaylı bir tartışma için #1024 ve #490 sorun sayfalarına göz atın.
// kötü React.createClass({ _onClickSubmit() { // bişeyler yap }, // diğer şeyler }); // iyi class extends React.Component { onClickSubmit() { // bişeyler yap } // diğer şeyler }
-
render
metodunda bir değer döndürdüğünüze emin olun. eslint:react/require-render-return
// kötü render() { (<div />); } // iyi render() { return (<div />); }
class extends React.Component
için sıralama:
- optional
static
methods constructor
getChildContext
componentWillMount
componentDidMount
componentWillReceiveProps
shouldComponentUpdate
componentWillUpdate
componentDidUpdate
componentWillUnmount
- clickHandlers or eventHandlers like
onClickSubmit()
oronChangeDescription()
- getter methods for
render
likegetSelectReason()
orgetFooterContent()
- optional render methods like
renderNavigation()
orrenderProfilePicture()
render
-
propTypes
,defaultProps
,contextTypes
, vs. nasıl tanımlanır: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;
-
React.createClass
için sıralama: eslint:react/sort-comp
displayName
propTypes
contextTypes
childContextTypes
mixins
statics
defaultProps
getDefaultProps
getInitialState
getChildContext
componentWillMount
componentDidMount
componentWillReceiveProps
shouldComponentUpdate
componentWillUpdate
componentDidUpdate
componentWillUnmount
- clickHandlers or eventHandlers like
onClickSubmit()
oronChangeDescription()
- getter methods for
render
likegetSelectReason()
orgetFooterContent()
- optional render methods like
renderNavigation()
orrenderProfilePicture()
render
isMounted
kullanmayın. eslint:react/no-is-mounted
Neden?
isMounted
düzene uygun değildir, ES6 sınıflarını kullanırken geçerli değildir, ve resmi olarak kaldırılmak için üzeredir.
Bu JSX/React stil rehberi aynı zamanda diğer dillerde de mevcuttur:
- 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