67
60

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

React Style Guide を日本語訳した

Posted at

react-style-guideの日本語訳が見つからなかったので、ざっと読むだけでなく英語の勉強がてらオレオレな和訳をしてみた。(半分ぐらい個人用メモ状態です)

(わからない部分はGoogle翻訳に頼ったし諦めたりしたりしたし)ものすごい誤訳意訳口語訳多数だと思うので、指摘等いただけると幸いです。


Reactの"独特な"考え方は今までこれといってスッキリと書くことができなかった。
だから私は、所属するチームで過去数ヶ月の間で使ってみたイケてる感じのReactの書き方についてまとめてみようと考えた。

この記事は、React-Componentsに限定した範囲での話をします。
(JavaScriptの)プログラミング全体のスタイルや、componentization(Web Componentsを用いた開発?)、Fluxの概念とかの話ではないです。
同様に、ドキュメントは生きていますし、これより良いReactの書き方は有ると思いますので、ぜひフィードバックしてね :)

##構造論
-Method Organization

だいたいこんな感じの種類のライフサイクルメソッドを使います
(この順番で書きます)

React.createClass({  
  displayName : '',
  propTypes: {},
  mixins : [],
  getInitialState : function() {},
  componentWillMount : function() {},
  componentWillUnmount : function() {},
  render : function() {}
});

displayNameは開発中にデバッグするのが楽になるので設定しといたほうがいいよ!
あと私は一番上に置くのが好みで、propTypesとmixinsをその次に書くよ。

PropTypeはpropsの入力値のバリデーションチェックに加えて、あなたがこのコンポーネントをどんな感じに使って欲しいか、という明確なドキュメントを書くときに特に使えるよ!

もしあなたがコンポーネント内で関数(function)をカスタマイズしたかったら、私はそれを(ReactのAPIと)区別するために頭にアンダースコアをつけることを好みます。
で、render functionの上に書きます。

React.createClass({  
  displayName : '',
  propTypes: {},
  mixins : [],
  getInitialState : function() {},
  componentWillMount : function() {},
  componentWillUnmount : function() {},
  _onChange : function() {},
  _onCreate : function() {},
  render : function() {}
});

render functionより下のほうに書くべきかとも考えたんだけど、現実的に考えるとComponentを一番下までスクロールしたときにはrender functionがいつでも一番下に来ていることがわかっていた方がいいよね。

同じように、私は出来る限りすべてのコンポーネントのJSXはrenderの中に書かれていることを好みます。

##条件付きのHTML
Conditional HTML

(繰り返すことに価値がある ?)
JSXでは、HTMLの中の{}の中身はなんでもJavaScriptに評価されることに価値があります。

なので、あなたがなんかシンプルな条件文をrenderしたいと思ったら、あなたは同じHTMLの中で三項演算子(ternaries)を使えばいいです。

{this.state.show && 'This is Shown'}
{this.state.on ? ‘On’ : ‘Off’}

(HTMLを作るときに)もっと複雑なものについては、suffix(末尾)にHtmlとつけて変数として書いておいて、render関数内では変数として展開します。

var dinosaurHtml = '';  
if (this.state.showDinosaurs) {  
  dinosaurHtml = (
    <section>
      <DinosaurTable />
      <DinosaurPager />
    </section>
  );
}

return (  
  <div>
    ...
    {dinosaurHtml}
    ...
  </div>
);

##返り値や変数としてのJSX
JSX as a Variable or Return Value

JSXで複数行になる場合は
こんな感じで(括弧で)ラップして挿入します

var multilineJsx = (  
  <header>
    <Logo />
    <Nav />
  </header>
);

一行だったらこんな感じで挿入します(括弧つけないって意味だと思う)

var singleLineJsx = <h1>Simple JSX</h1>; 

しかし、(一行だと)複雑な感じだったり、今後拡張されそうな場合とかは(括弧で)ラップします。可読性と利便性のために。

##閉じタグ
Self-Closing Tags

子要素の無いコンポーネントは↑で出したLogoをみたいな感じで自分のタグの中で閉じます。

<Logo />  

↓みたいに不必要にタグを分けないように

<Logo></Logo> 

##Listのイテレーション
List Iterations

私はlistのイテレーションはdinosaurHtmlであげたような感じで使います。
特にそれぞれのlist itemをコンポーネントとしてレンダリングしない限り、listのイテレーションは(HTMLの)インラインに書いたほうが良いことがわかったんです。
あなたは長くなった1行を減らしたくなるかもしれないけどね。

render : function() {  
  return (
    <ul>
      {this.state.dinosaursList.map(dinosaur => <DinosaurItem item={dinosaur} />)}
    </ul>
  );
}

JSXのharmony flagが必要です。
アロー関数(fat arrow)とかテンプレートリテラル(template strings)とか分割代入(Destructuring assignment)とかレストパラメータとかその辺を使うために。
http://kangax.github.io/compat-table/es6/#jsx に列挙されてます。

JSXをわざわざコンパイルしているんなら、ES6の機能も使えるから、JSXのharmony flagとかbabel的なものとかを使ったほうがいいよ(私らはbabelを使ってます)

##フォーム
Forms

フォームのstateをコンポーネントの内部とか、例えばFluxのStoreとか外部に保存しておくために、ReactのAddonsのLinkedStateMininを使うとか、自分でhandler(s)を書いておくべきだ。
LinkedStateMixinを使うのは、ここのドキュメントをみるとめっちゃ簡単に使えます。

もしFluxのstoreのハンドラを使うんだったら、↓みたいな感じで1つの抽象的に書くことができて、それぞれのフィールドに運ぶことができます。

<input type="text" value={this.state.newDinosaurName} onChange={this.inputHandler.bind(this, 'newDinosaurName')} />  

inputHandlerはこんな感じ

function(fieldName, event) {  
  actions.propagateValue({
    field : fieldName,
    value : event.target.value
  });
}

Hacker Newsスレッドで@insinが書いていた更にいいパターンが、すべてのinput formでonChangeハンドラを置かずに、以下のようにほんとに必要なハンドラを1つだけ置いている

<form onChange={this.inputHandler}>  
  ...
    <input type="text" name="newDinosaurName" value={this.state.newDinosaurName} />
  ...
</form>  

そのときのinputHanderはこんな感じ

function(event) {  
  actions.propagateValue({
    field : event.target.name,
    value : event.target.value
  });
}

※訂正:
この記事ではコントロール出来ないフォームフィールドが〜
直接Stateでコントロールできるようなフォームフィールドのほうが好ましいと書いてあった。
この意見は修飾されていないものだった(?)
私はそれがフォームフィールドとStateの値が一致する
と無駄なDOMアクセスを避けるために有益だと思った。

##フォーマットの整え方
Formatting Attributes

下みたいな長いinput formでは、綺麗で簡単に見えるように改行しましょう

<input  
  type="text"
  value={this.state.newDinosaurName}
  onChange={this.inputHandler.bind(this, 
  'newDinosaurName')} />

対照的に、タグで整列させるのも、どちらもインデントがないものよりかは読みやすいと思うけど、↑よりもちょっと読むのが大変かも

<input type="text"  
       value={this.state.newDinosaurName}
       onChange={this.inputHandler.bind(this,
       'newDinosaurName')} />

##終わりに
Closing

今回、我々がReactを書いている中で使えそうだと思ったパターンをほんの少し紹介しましたが、決して"こうすべきだ!"と強制するものではありません。
もし、反対なアイデアとかあったらコメント欄とかでお申し出ください。
(ベストプラクティス的な)この種の議論はReactのエコシステム全体に対してとても有益なものになるでしょう。

私はぜひともaddress stylingとかcomponentization(minixsの使いドコロとか、propsとstateの使い分け方とか会話方法?とか)とか、Fluxについて書いてあるstyle guideを読んでみたいです

よんでくれてありがとー

67
60
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
67
60

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?