2017-07-28 74 views
0

我有一个带有套接字的服务器和客户端,它们之间的连接正在工作,但是我的React组件不刷新。Socket.io不刷新React组件

我的组件是一个由元素数组打印的出版物,我从API和Express(连接到MySQL数据库)获取所有这些信息。

这是我的阵营文件:

import React, { Component } from 'react'; 
import './component.css'; 
import io from 'socket.io-client'; 

import Msg from './components/Msg'; 
import ItemMsg from './components/ItemMsg'; 
import Sidebar from './components/Sidebar'; 
let socket = io('http://localhost:8082'); 

class App extends Component { 

    constructor(props){ 
    super(props); 

    this.state = { 
     ids: [] 
    }; 

    } 


    componentDidMount() { 

    socket.on('update:component', (data) => { 

     // Debug line 
     console.log('recived message:', data); 

     // Update state 
     this.setState(prevState => { 

     // Get previous state 
     const { ids } = prevState; 

     // Add new item to array 
     ids.push(data); 

     // Debug line 
     console.log('new state:', ids); 

     // Return new state 
     return { ids }; 
     }); 
    }); 

    fetch('/todos/ids') 
    .then((response) => response.json()) 
    .then((responseJson) => { 
     this.setState({ids: responseJson.data}) 
     console.log(responseJson.data); 
    }) 
    } 

    render() { 
    return (
     <div> 
     <Sidebar/> 
     <Msg/> 
     <ul> 
      { 
      this.state.ids.map((i, k) => 
       <li key={k}><ItemMsg idfromparent={i.ID_Publicacion}/></li> 
     ) 
     } 
     </ul> 
    </div> 
); 
} 
} 

export default App; 

这是我的服务器上的文件:

var express = require('express'); 
var http = require('http'); 
var app = express(); 
var server = http.createServer(app); 
var io = require('socket.io').listen(server); 

var messages = [{ 
    id: 1, 
    text: "I'm a message", 
    author: "I'm the author" 
}]; 

app.use(express.static('public')); 

app.use(function (req, res, next) { 
    res.header('Access-Control-Allow-Origin', '*'); 
    res.header('Access-Control-Allow-Headers', 'Origin, X-Requested-With, Content-Type, Accept-Type'); 
    res.header('Access-Control-Allow-Credentials', 'true'); 
    next(); 
}) 

app.get('/hello', function(req, res) { 
    res.status(200).send("Hello World!"); 
}); 

io.on('connection', function(socket) { 
    console.log('Alguien se ha conectado con Sockets'); 

    socket.on('update:component', function(data) { 
    socket.emit('Thanks', data); 
    console.log(data); 
    }); 
}); 

server.listen(8082, function() { 
    console.log("Server corriendo en http://localhost:8082"); 
}); 

插入组件:

import React, { Component } from 'react'; 
import avatar from '../avatar.jpg' 
import '../component.css' 
import io from 'socket.io-client'; 
let socket = io('http://localhost:8082'); 


class Msg extends Component { 

    constructor(props) { 
    super(props); 
    this.handleSubmit = this.handleSubmit.bind(this); 
    this.state = {value: ''}; 
    this.handleChange = this.handleChange.bind(this); 
    } 

    handleSubmit(e){ 
    e.preventDefault(); 
    var self = this; 

    // On submit of the form, send a POST request with the data to the server. 
    fetch('/todo/meterla',{ 
     method: 'POST', 
     body:JSON.stringify({ 
     publicacion: self.refs.task.value 
     }), 
     headers: {"Content-Type": "application/json"} 
    }) 
    .then(function(response){ 
     return response.json() 
    }).then(function(data){ 
     console.log('json:', data); 
     socket.emit('update:component', data); 
    }); 
    } 

componentDidMount(){ 
    socket.on('update:component', (data) => { 
    // Update state 
    this.setState(prevState => { 

     // Get previous state 
     const { ids } = prevState; 

     // Add new item to array 
     ids.push(data); 

     // Return new state 
     return { ids }; 
    }); 
    }); 
} 

handleChange(event) { 

    this.setState({value: event.target.value}); 
} 

    render(data) { 
    return (
     <div> 
     <form className="post" action="index.html" method="post" onSubmit={this.handleSubmit.bind(this)}> 
      <img className="avatar" src={avatar} alt="" /> 
      <input type="text" placeholder="Escribe algo" ref="task" value={this.state.value} onChange={this.handleChange}/> 
      <input type="submit" value="Publicar" /> 
     </form> 
     </div> 
    ); 
    } 
} 

export default Msg; 

这是日志的结果 enter image description here

+0

什么也正是这个问题?你有没有得到任何错误? – btzr

+0

尝试调试'{console.log(this.state.ids)}' – btzr

+0

^^在'render()' – btzr

回答

1

问题

I want to automatically refresh the component when I insert a data in the database, and thats why i've implemnted the websockets. The fetch brings me a select from the database

我猜你的意思是每次您发送post要求低谷handleSubmit(),对不对?

发布采购信息

处理您的POST请求与express
你需要在每次发送post请求时,发出一个自定义事件:

Emits an event to the socket identified by the string name. Any other parameters can be included.

app.post("/foo", function(req, res, next) { 
    io.sockets.emit("foo", req.body); 
    res.send({}); 
}); 

参见:docs

从输入中获取价值

In HTML, form elements such as <input> , <textarea> , and <select> typically maintain their own state and update it based on user input. In React, mutable state is typically kept in the state property of components, and only updated with setState().

参见:Controlled components

// Set state 
this.state = {value: ''}; 
... 

handleChange(event) { 
    this.setState({value: event.target.value}); 
} 
... 

// Render 
    <input type="text" value={this.state.value} onChange={this.handleChange} /> 

处理事件

This binding is necessary to make this work in the callback

this.handleSubmit = this.handleSubmit.bind(this); 
this.handleChange = this.handleChange.bind(this); 

参见:docs

设置反应成分+插座。IO

const io = require('socket.io-client'); 
... 
class MyComponent extends React.Component { 

    ComponentWillMount(){ 
     this.socket = io(); 
    } 
} 

参见:Set up React component to listen to socket.io

监听事件

Register a new handler for the given event. See: docs

你只是updating国家只有一个时间fetch(),触发updateState一个监听器里:

ComponentDidMount(){ 

    // Listen for custom event and add handler 
    this.socket.on('update:component', (data) => { 
    ... 

正确使用状态

Because this.props and this.state may be updated asynchronously, you should not rely on their values for calculating the next state.

不要修改State直接,在那里你可以指定this.state的唯一地方是构造函数:

 this.setState(prevState => { 

      // Get previous state 
      const { ids } = prevState; 

      // Add new item to array 
      ids.push(data); 

      // Return new state 
      return { ids }; 
    }); 
} 

渲染

JSX allows embedding any expressions in curly braces so we could inline the map() result

{ 
    this.state.ids.map((i, k) => 
     <li key={k}><ItemMsg idfromparent={i.ID_Publicacion}/></li> 
    ); 
} 

Github上

websockets_react/issues/1

资源

+0

它显示我这个错误在这个部分 “无法读取的未定义的属性 '的setState'” : handleChange(事件){ this.setState({值:event.target.value}); } –

+0

你忘了绑定:'this.handleChange = this.handleChange.bind(this);' – btzr

+0

请阅读docs:react和socket.io – btzr