├── lib └── .gitkeep ├── .npmignore ├── .babelrc ├── src ├── index.js ├── dist.js ├── listener.js └── socket.js ├── .gitignore ├── .travis.yml ├── test.js ├── LICENSE ├── .eslintrc ├── README.md ├── package.json └── dist.js /lib/.gitkeep: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /.npmignore: -------------------------------------------------------------------------------- 1 | dist.js 2 | src 3 | test.js 4 | *.test.js -------------------------------------------------------------------------------- /.babelrc: -------------------------------------------------------------------------------- 1 | { 2 | "presets": [ 3 | "react", 4 | "es2015", 5 | "stage-2" 6 | ] 7 | } -------------------------------------------------------------------------------- /src/index.js: -------------------------------------------------------------------------------- 1 | import Socket from './socket'; 2 | import Listener from './listener'; 3 | 4 | export default {Socket, Listener}; 5 | -------------------------------------------------------------------------------- /src/dist.js: -------------------------------------------------------------------------------- 1 | import Socket from './socket'; 2 | import Listener from './listener'; 3 | 4 | window.ReactSocket = {Socket, Listener}; 5 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | .DS_Store 3 | .idea 4 | *.log 5 | .nyc_output 6 | .nyc_cache 7 | /coverage 8 | /lib/* 9 | !/lib/.gitkeep 10 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | language: node_js 2 | node_js : 3 | - "iojs" 4 | deploy: 5 | provider: npm 6 | email: eduardo@comakai.com 7 | api_key: 8 | secure: JX1zgdfsP3rwISjl2mn6LNFOwNYcy2XIuL1mHXhAllDE5utvvaum8/zt/PWuBY7qlocGN8NZfjDsWc3PlDiezs9o0JZ0y0ipBgcPLPJJqbXc6U5EIVAUwnOMs7HorF1yz4S5T4GfBWwWfhFPr3setSHmRDTKyjmUBUqnvUj9Pq8= 9 | on: 10 | tags: true 11 | repo: coma/react-socket -------------------------------------------------------------------------------- /test.js: -------------------------------------------------------------------------------- 1 | const path = require('path'), 2 | glob = require('glob'), 3 | tape = require('tape'), 4 | report = require('faucet'), 5 | ignore = require('ignore-styles'); 6 | 7 | tape 8 | .createStream() 9 | .pipe(report()) 10 | .pipe(process.stdout); 11 | 12 | let files = process.argv.slice(2); 13 | 14 | if (files.length < 1) { 15 | 16 | files = glob.sync('src/**/*.test.js'); 17 | } 18 | 19 | files.map(file => require(path.resolve(__dirname, file))); -------------------------------------------------------------------------------- /src/listener.js: -------------------------------------------------------------------------------- 1 | import React, { Component, PropTypes } from 'react'; 2 | import { NAME, get } from './socket'; 3 | 4 | class Listener extends Component { 5 | 6 | componentWillMount () { 7 | 8 | const {socket, event, callback} = this.props; 9 | 10 | this.socket = get(socket); 11 | this.socket.on(event, callback); 12 | } 13 | 14 | componentWillUnmount () { 15 | 16 | const {event, callback} = this.props; 17 | 18 | this.socket.off(event, callback); 19 | } 20 | 21 | render () { 22 | 23 | return false; 24 | } 25 | } 26 | 27 | Listener.displayName = 'SocketListener'; 28 | 29 | Listener.propTypes = { 30 | socket : PropTypes.string, 31 | event : PropTypes.string.isRequired, 32 | callback: PropTypes.func.isRequired 33 | }; 34 | 35 | Listener.defaultProps = { 36 | socket: NAME 37 | }; 38 | 39 | export default Listener; -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2015 Eduardo García Sanz 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | 23 | -------------------------------------------------------------------------------- /src/socket.js: -------------------------------------------------------------------------------- 1 | import React, { Component, PropTypes } from 'react'; 2 | 3 | export const NAME = 'default'; 4 | 5 | const SOCKETS = {}; 6 | 7 | export const has = name => SOCKETS.hasOwnProperty(name); 8 | 9 | export const get = (name = NAME) => { 10 | 11 | if (!has(name)) { 12 | 13 | throw new Error(`There is no "${ name }" socket mounted.`); 14 | } 15 | 16 | return SOCKETS[name]; 17 | }; 18 | 19 | class Socket extends Component { 20 | 21 | componentWillMount () { 22 | 23 | const {name, url, options} = this.props; 24 | 25 | if (has(name)) { 26 | 27 | throw new Error(`Another "${ name }" socket is already mounted.`); 28 | } 29 | 30 | SOCKETS[name] = io(url, options); 31 | } 32 | 33 | componentWillUnmount () { 34 | 35 | const {name} = this.props; 36 | 37 | SOCKETS[name].disconnect(); 38 | delete SOCKETS[name]; 39 | } 40 | 41 | render () { 42 | 43 | return false; 44 | } 45 | } 46 | 47 | Socket.displayName = 'Socket'; 48 | 49 | Socket.propTypes = { 50 | url : PropTypes.string, 51 | name : PropTypes.string, 52 | options: PropTypes.object 53 | }; 54 | 55 | Socket.defaultProps = { 56 | url : '/', 57 | name: NAME 58 | }; 59 | 60 | export default Socket; -------------------------------------------------------------------------------- /.eslintrc: -------------------------------------------------------------------------------- 1 | { 2 | "parser": "babel-eslint", 3 | "env" : { 4 | "browser": true 5 | }, 6 | "rules" : { 7 | "no-class-assign" : 2, 8 | "no-confusing-arrow" : 0, 9 | "no-const-assign" : 2, 10 | "no-dupe-class-members" : 2, 11 | "no-new-symbol" : 2, 12 | "no-this-before-super" : 2, 13 | "no-useless-constructor" : 2, 14 | "no-var" : 2, 15 | "arrow-body-style" : [2, "as-needed"], 16 | "arrow-parens" : 0, 17 | "arrow-spacing" : [ 18 | 2, 19 | { 20 | "before": true, 21 | "after" : true 22 | } 23 | ], 24 | "constructor-super" : 2, 25 | "object-shorthand" : [2, "always"], 26 | "prefer-arrow-callback" : 2, 27 | "prefer-const" : 2, 28 | "prefer-rest-params" : 2, 29 | "prefer-spread" : 2, 30 | "prefer-template" : 1, 31 | "template-curly-spacing" : [2, "always"], 32 | "strict" : 0, 33 | "new-cap" : 0, 34 | "eqeqeq" : 2, 35 | "curly" : 2, 36 | "quotes" : [1, "single"], 37 | "no-unreachable" : 2, 38 | "space-before-blocks" : 2, 39 | "space-before-function-paren": 2, 40 | "no-multi-spaces" : 0, 41 | "key-spacing" : 0, 42 | "no-mixed-requires" : 0 43 | } 44 | } -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | react-socket 2 | ============ 3 | 4 | [](https://travis-ci.org/coma/react-socket) 5 | [](http://david-dm.org/coma/react-socket) 6 | [](http://badge.fury.io/js/react-socket) 7 | 8 | A React wrapper for Socket.IO 9 | 10 | Usage 11 | ----- 12 | 13 | Just mount a socket on one of your components: 14 | 15 | ```javascript 16 | var React = require('react'), 17 | Socket = require('react-socket').Socket; 18 | 19 | module.exports = module.exports = React.createClass({ 20 | render: function () { 21 | 22 | return ( 23 |