Socket.io没有刷新React组件

时间:2017-07-28 22:08:37

标签: node.js reactjs express socket.io

我有一个带套接字的服务器和客户端,它们之间的连接正在进行,但我的React组件没有刷新。

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

这是我的React文件:

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

1 个答案:

答案 0 :(得分:1)

问题

  

我想在数据库中插入数据时自动刷新组件,这就是为什么我实现了websockets。 fetch为我提供了数据库中的选择

我猜您的意思是每次通过post发送handleSubmit()请求时,对吗?

发布请求

使用express处理您的帖子请求:
每次发送post请求时,您都需要发出自定义事件:

  

将事件发送到由字符串名称标识的套接字。可以包括任何其他参数。

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

请参阅:docs

从输入中获取值

  

在HTML中,<input><textarea><select>等表单元素通常会维护自己的状态,并根据用户输入进行更新。在React中,可变状态通常保存在组件的state属性中,并且仅使用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在回调中起作用是必要的

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

请参阅:docs

安装程序反应组件+ socket.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

听取事件

  

为给定事件注册新的处理程序。   请参阅:docs

updating只有fetch()个状态,在听众中触发updateState

ComponentDidMount(){

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

正确使用状态

  

因为this.props和this.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允许在花括号中嵌入任何表达式,因此我们可以内联map()结果

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

Github的

websockets_react/issues/1

资源