From 2521c5235164244e927d3b7e5d87435357c32ea7 Mon Sep 17 00:00:00 2001 From: Lee Bannard Date: Sat, 12 Dec 2015 23:33:35 +0000 Subject: [PATCH] Update readme for v3 release --- README.md | 155 ++++++++++++++++++++++++++++++++++++++++++------------ 1 file changed, 120 insertions(+), 35 deletions(-) diff --git a/README.md b/README.md index 3f09dbd8..0af69639 100644 --- a/README.md +++ b/README.md @@ -7,8 +7,7 @@ A live-editing time travel environment for [Redux](https://github.com/rackt/redu [![build status](https://img.shields.io/travis/gaearon/redux-devtools/master.svg?style=flat-square)](https://travis-ci.org/gaearon/redux-devtools) [![npm version](https://img.shields.io/npm/v/redux-devtools.svg?style=flat-square)](https://www.npmjs.com/package/redux-devtools) [![npm downloads](https://img.shields.io/npm/dm/redux-devtools.svg?style=flat-square)](https://www.npmjs.com/package/redux-devtools) -[![redux channel on slack](https://img.shields.io/badge/slack-redux@reactiflux-61DAFB.svg?style=flat-square)](http://www.reactiflux.com) - +[![redux channel on discord](https://img.shields.io/badge/discord-redux@reactiflux-738bd7.svg?style=flat-square)](https://discord.gg/0ZcbPKXt5bWb10Ma) ![](http://i.imgur.com/J4GeW0M.gif) @@ -16,10 +15,9 @@ A live-editing time travel environment for [Redux](https://github.com/rackt/redu * Lets you inspect every state and action payload * Lets you go back in time by “cancelling” actions -* If you change the reducer code, each “staged” action will be re-evaluted +* If you change the reducer code, each “staged” action will be re-evaluated * If the reducers throw, you will see during which action this happened, and what the error was * With `persistState()` store enhancer, you can persist debug sessions across page reloads -* Toggle visibility with Ctrl+H ### Installation @@ -29,57 +27,152 @@ npm install --save-dev redux-devtools DevTools is a [store enhancer](http://rackt.github.io/redux/docs/Glossary.html#store-enhancer), which should be added to your middleware stack *after* [`applyMiddleware`](http://rackt.github.io/redux/docs/api/applyMiddleware.html) as `applyMiddleware` is potentially asynchronous. Otherwise, DevTools won’t see the raw actions emitted by asynchronous middleware such as [redux-promise](https://github.com/acdlite/redux-promise) or [redux-thunk](https://github.com/gaearon/redux-thunk). -To install, firstly import `devTools` into your root React component: +To use, first create a `DevTools` component by passing a `monitor` component to `createDevTools`. In the following example our `monitor` consists of [`redux-devtools-log-monitor`](https://github.com/gaearon/redux-devtools-log-monitor) docked within [`redux-devtools-dock-monitor`](https://github.com/gaearon/redux-devtools-dock-monitor): + +####containers/DevTools.js ```js -// Redux utility functions -import { compose, createStore, applyMiddleware } from 'redux'; +import React from 'react'; -// Redux DevTools store enhancers -import { devTools, persistState } from 'redux-devtools'; +// createDevTools takes a monitor and produces a DevTools component +import { createDevTools } from 'redux-devtools'; -// A monitor component for Redux DevTools +// Monitor component for Redux DevTools import LogMonitor from 'redux-devtools-log-monitor'; + +// Dock component to contain a Redux DevTools monitor +import DockMonitor from 'redux-devtools-dock-monitor'; + +export default createDevTools( + + + +); ``` -Then, add `devTools` to your store enhancers, and create your store: +Note that it is not essential to put [`redux-devtools-log-monitor`](https://github.com/gaearon/redux-devtools-log-monitor) inside the dock component, it can be placed wherever you like in the component tree. + +Next add `instrument()` and (optionally) `persistState()` to your store enhancers, and create your store: ```js + +import { createStore, compose } from 'redux'; +import { persistState } from 'redux-devtools'; +import rootReducer from '../reducers'; +import DevTools from '../containers/DevTools'; + const finalCreateStore = compose( // Enables your middleware: applyMiddleware(m1, m2, m3), // any Redux middleware, e.g. redux-thunk - // Provides support for DevTools: - devTools(), + // Provide support for DevTools + DevTools.instrument(), // Lets you write ?debug_session= in address bar to persist debug sessions - persistState(window.location.href.match(/[?&]debug_session=([^&]+)\b/)) + persistState( + window.location.href.match( + /[?&]debug_session=([^&]+)\b/ + ) + ) )(createStore); -const store = finalCreateStore(reducer); +export default function configureStore(initialState) { + const store = finalCreateStore(rootReducer, initialState); + + // enable hot reloading for the store + if (module.hot) { + module.hot.accept('../reducers', () => + store.replaceReducer(require('../reducers')) + ); + } + + return store; +} ``` -Finally, include the `DevTools` in your page. You may pass either `LogMonitor` (the default one) or any of the custom monitors described below. +Finally, include the DevTools component in your page: + +####index.js ```js +import React from 'react'; +import { render } from 'react-dom'; +import { Provider } from 'react-redux'; +import configureStore from './store/configureStore'; +import TodoApp from './TodoApp'; +import DevTools from './DevTools'; + +const store = configureStore(); + +render( + +
+ + +
+
+ document.getElementById('app') +); +``` + +**Make sure to only use DevTools in development!** In production it will be terribly slow because currently actions just accumulate forever. + +In Webpack, you can use `DefinePlugin` to turn magic constants like `__DEV__` into `true` or `false` depending on the environment, and import and render `redux-devtools` conditionally behind `if (__DEV__)`. Then, if you have an Uglify step before production, Uglify will eliminate dead `if (false)` branches with `redux-devtools` imports. + +If you are using ES6 modules with Webpack 1.x, you might try putting your `import` statement inside an `if (__DEV__)` to exclude the DevTools package from your production bundle. This will not work. However, you can work around this by creating separate `dev` and `prod` Root components that are dynamically imported using commonJS `require`: + +####containers/Root.js + +```js +if (process.env.NODE_ENV === 'production') { + module.exports = require('./Root.prod'); +} else { + module.exports = require('./Root.dev'); +} +``` + +####Root.dev.js + +```js +import React, { Component } from 'react'; +import { Provider } from 'react-redux'; +import TodoApp from './TodoApp'; +import DevTools from './DevTools'; + export default class Root extends Component { render() { + const { store } = this.props; return ( -
- - - - - -
+ +
+ + +
+
); } } ``` -**Make sure to only apply `devTools()` in development!** In production, this will be terribly slow because actions just accumulate forever. (We'll need to implement a rolling window for dev too.) +####Root.prod.js -For example, in Webpack, you can use `DefinePlugin` to turn magic constants like `__DEV__` into `true` or `false` depending on the environment, and import and render `redux-devtools` conditionally behind `if (__DEV__)`. Then, if you have an Uglify step before production, Uglify will eliminate dead `if (false)` branches with `redux-devtools` imports. Here is [an example](https://github.com/erikras/react-redux-universal-hot-example/) that adds Redux DevTools handling the production case correctly. +```js +import React, { Component } from 'react'; +import { Provider } from 'react-redux'; +import TodoApp from './TodoApp'; + +export default class Root extends Component { + render() { + const { store } = this.props; + return ( + + + + ); + } +} +``` ### Running Examples @@ -103,7 +196,7 @@ Oh, and you can do the same with the TodoMVC example as well. ### Custom Monitors -**You can build a completely custom UI for it** because `` accepts a `monitor` React component prop. The included `LogMonitor` is just an example. +**DevTools accepts monitor components so you can build a completely custom UI.** [`redux-devtools-log-monitor`](https://github.com/gaearon/redux-devtools-log-monitor) and [`redux-devtools-dock-monitor`](https://github.com/gaearon/redux-devtools-dock-monitor) are just examples of what is possible. **[I challenge you to build a custom monitor for Redux DevTools!](https://github.com/gaearon/redux-devtools/issues/3)** @@ -112,22 +205,14 @@ Some crazy ideas for custom monitors: * A slider that lets you jump between computed states just by dragging it * An in-app layer that shows the last N states right in the app (e.g. for animation) * A time machine like interface where the last N states of your app reside on different Z layers -* Feel free to come up with and implement your own! Check `LogMonitor` propTypes to see what you can do. +* Feel free to come up with and implement your own! Check [`redux-devtools-log-monitor`](https://github.com/gaearon/redux-devtools-log-monitor) propTypes to see what you can do. In fact some of these are implemented already: -#### [redux-devtools-diff-monitor](https://github.com/whetstone/redux-devtools-diff-monitor) - -![](http://i.imgur.com/rvCR9OQ.png) - #### [redux-slider-monitor](https://github.com/calesce/redux-slider-monitor) ![](https://camo.githubusercontent.com/d61984306d27d5e0739efc2d57c56ba7aed7996c/68747470733a2f2f73332e616d617a6f6e6177732e636f6d2f662e636c2e6c792f6974656d732f3269314c3147316e3161316833793161324f31772f53637265656e2532305265636f7264696e67253230323031352d30382d3034253230617425323030372e3435253230504d2e676966) -#### [redux-devtools-gentest-plugin](https://github.com/lapanoid/redux-devtools-gentest-plugin) - -![](https://camo.githubusercontent.com/71452cc55bc2ac2016dc05e4b6207c5777028a67/687474703a2f2f646c312e6a6f78692e6e65742f64726976652f303031302f333937372f3639323130352f3135303731362f643235343637613236362e706e67) - #### Keep them coming! Create a PR to add your custom monitor.