React開發中經常使用的工具集錦

本文從屬於筆者的React入門與最佳實踐系列。css

本文記錄了筆者在React開發中常見的一些工具插件,若是你想尋找合適的項目生成器或者模板,請參考筆者的使用Facebook的create-react-app快速構建React開發環境html

React Devtools

React Devtools是React官方提供的相似於瀏覽器調試臺的插件,能夠容許以查看組件的層次、各個組件的Props、States等等信息。使用方式也很簡單,直接在Firefox或者Chrome的加載項倉庫中搜索下載便可。node

React-StoryBook:開發中獨立於APP查看React組件

React Storybook能夠在你開發的過程當中將React組件獨立於整個應用程序進行查看,其主要特徵爲:react

  • 獨立的組件運行環境webpack

  • 組件的熱加載git

  • 能夠與Redux、Relay以及Meteor無縫集成es6

  • 支持CSSgithub

Quick Start

Installation

首先須要將React Storybook添加到應用中,使用npm進行安裝便可:web

npm i --save-dev @kadira/storybook

而後,將運行腳本添加到package.json文件中:npm

{
  ...
  "scripts": {
    "storybook": "start-storybook -p 9001"
  }
  ...
}

接下來,你就能夠直接輸入npm run storybook而後啓動開發模塊。

編寫測試用的Story

在測試環境搭建完成以後須要編寫一些Stories,便是測試故事。基原本說,一個Story就是一個單獨的組件的視圖,有點相似與一個測試用例,可是能夠在Storybook UI中直接查看。一個典型的測試Story以下所示:

// components/stories/button.js

import React from 'react';
import { storiesOf, action } from '@kadira/storybook';

storiesOf('Button', module)
  .add('with text', () => (
    <button onClick={action('clicked')}>My First Button</button>
  ))
  .add('with no text', () => (
    <button></button>
  ));

Configuration

在編寫好了Story以後須要告訴Storybook應該如何加載,須要進行一些簡單的配置,只要添加以下相似的內容到.storybook/config.js中:

import { configure } from '@kadira/storybook';

function loadStories() {
  require('../components/stories/button');
  // require as many stories as you need.
}

configure(loadStories, module);

接下來,能夠直接使用npm run storybook來運行界面。

CSS Support

有時候,咱們須要在進行組件預覽的時候導入額外的CSS文件,若是直接是在組件的JS內引入的CSS則能夠直接使用,譬如你能夠直接使用Material UI。而若是是使用Webpack的話能夠在config文件中添加以下webpack.config(.storybook/webpack.config.js):

var path = require('path')
var webpack = require('webpack')

module.exports = {

  ...

  module: {
    loaders: [
      {
        test: /\.js$/,
        loaders: [ 'babel' ],
        exclude: /node_modules/,
        include: __dirname
      },
      {
        test: /\.css?$/,
        loaders: [ 'style', 'raw' ],
        include: __dirname
      }
    ]
  }
}

若是是使用Meteor的話,能夠在Meteor app中添加以下配置:

const path = require('path');
module.exports = {
  module: {
    loaders: [
      {
        test: /\.css?$/,
        loaders: [ 'style', 'raw' ],
        include: path.resolve(__dirname, '../')
      }
    ]
  }
}

Stories

Redux

  • 組件

import React, { Component, PropTypes } from 'react'

import classnames from 'classnames'

import TodoTextInput from './TodoTextInput'



class TodoItem extends Component {

  constructor(props, context) {

    super(props, context)

    this.state = {

      editing: false

    }

  }



  handleDoubleClick() {

    this.setState({ editing: true })

  }



  handleSave(id, text) {

    if (text.length === 0) {

      this.props.deleteTodo(id)

    } else {

      this.props.editTodo(id, text)

    }

    this.setState({ editing: false })

  }



  render() {

    const { todo, completeTodo, deleteTodo } = this.props



    let element

    if (this.state.editing) {

      element = (

        <TodoTextInput text={todo.text}

                       editing={this.state.editing}

                       onSave={(text) => this.handleSave(todo.id, text)} />

      )

    } else {

      element = (

        <div className="view">

          <input className="toggle"

                 type="checkbox"

                 checked={todo.completed}

                 onChange={() => completeTodo(todo.id)} />

          <label onDoubleClick={this.handleDoubleClick.bind(this)}>

            {todo.text}

          </label>

          <button className="destroy"

                  onClick={() => deleteTodo(todo.id)} />

        </div>

      )

    }



    return (

      <li className={classnames({

        completed: todo.completed,

        editing: this.state.editing

      })}>

        {element}

      </li>

    )

  }

}



TodoItem.propTypes = {

  todo: PropTypes.object.isRequired,

  editTodo: PropTypes.func.isRequired,

  deleteTodo: PropTypes.func.isRequired,

  completeTodo: PropTypes.func.isRequired

}



export default TodoItem
  • Story

import React from 'react';

import TodoItem from '../TodoItem';

import { storiesOf, action } from '@kadira/storybook';



storiesOf('TodoItem', module)

  .add('not completed', () => {

    const todo = {

      id: 'the-id',

      text: 'Hello Todo',

      completed: false

    };



    return getItem(todo);

  })

  .add('completed', () => {

    const todo = {

      id: 'the-id',

      text: 'Hello Todo',

      completed: true

    };



    return getItem(todo);

  });





function getItem(todo) {

  return (

    <div className="todoapp">

      <div className="todo-list">

        <TodoItem

          todo={todo}

          editTodo={action('editTodo')}

          deleteTodo={action('deleteTodo')}

          completeTodo={action('completeTodo')}/>

      </div>

    </div>

  );

}

HTML2JSX:智能地將HTML文件轉化爲JSX格式

對於大量現存的基於HTML開發的網頁,咱們可能須要將它們轉化爲JSX的語法,筆者推薦使用html-to-react-components這個工具,能夠自動將HTML標籤轉化爲JSX的標籤:

usage example animation

$ npm i -g html-to-react-components
$ html2react ./src/*.html -c stateless -m es6 -d _ -o components -e jsx

react-monocle:可視化地展現React組件的層次結構

React Monocle是一個幫助開發人員可視化瀏覽React組件的層次結構的工具,其大概的功能以下所示:

React Monocle會遍歷你的React源文件來構建一顆基於React組件的可視化樹,並且隨着你的應用程序狀態的變化,譬如存儲在Redux中的狀態的變化也會動態地來修正層次結構。該工具的安裝方式也十分簡單:

npm install -g react-monocle

monocle -c <html> -b <bundle>

why-did-you-update:提醒你沒必要要的重渲染

該函數會在出現沒必要要的重渲染的時候提醒你。使用方法也很簡單:

import React from 'react'

if (process.env.NODE_ENV !== 'production') {
  const {whyDidYouUpdate} = require('why-did-you-update')
  whyDidYouUpdate(React)
}

相關文章
相關標籤/搜索