Передача WS-соединения детям через реквизит React - PullRequest
1 голос
/ 11 марта 2019

Я использую Ratchet на внутреннем PHP-сервере для запуска веб-сокета и использую React в качестве внешнего интерфейса.

У меня открыта розетка, и я могу без проблем подключиться через JS.

Проблема, с которой я столкнулся, заключается в том, что я не могу передать соединение через веб-сокет каким-либо дочерним компонентам.

Например, у меня есть компонент чата с 3 подкомпонентами:

Main (оболочка для всего), Closed (закрытое состояние всплывающего окна чата), Open (отображает все сообщения и т. Д.) И Input (раздел ввода формы, который обрабатывает новый сообщения).

Наиболее логичное место для инициализации websocket - компонент Main, поэтому я делаю это, а затем передаю соединение дочернему компоненту Open:

componentDidMount() {
  this._isMounted = true;
  this.openWebsocket();
}

openWebsocket = () => {
  this.conn = new WebSocket('ws://localhost:8080');
  this.conn.onopen = () => {
    console.log('Connected!');
  };

  this.conn.onmessage = e => {
    console.log(e.data);
  };
};

......

<Open
   conn={this.conn}
/>

А затем в Open я передаю его компоненту Input (который является потомком Open):

<Input conn={this.props.conn} />

......

Open.propTypes = {
  conn: PropTypes.func.isRequired
}

Наконец-то в Input Я пытаюсь использовать его:

this.props.conn.send(this.state.msg);

......

Input.propTypes = {
  conn: PropTypes.func.isRequired
}

и выдает ошибки ...

Если я пытаюсь потребовать conn в качестве func PropType (как указано выше), он говорит, что объект был предоставлен. И если мне потребуется conn как object, то ничего не произойдет. Нет ошибок, но функция conn .send явно не вызывается.

Затем я попытался передать функцию .send в качестве реквизита:

<Open
   conn={this.conn.send}
/>

Но выдает Illegal invocation ошибку!

Итак, как передать соединение через веб-сокет дочерним компонентам в React?

1 Ответ

0 голосов
/ 18 марта 2019

Ответ был прост, и я почувствовал себя немного глупо после того, как перечитал свой вопрос, когда ответ выскочил на меня.

В основном все работает так, как ожидалось, и только для записи Proptypeскорее всего это object.Я просто не читал ответ, который отправлял обратно клиенту, где-нибудь в моем коде переднего плана.onmessage было отсутствующей ссылкой.В моем случае я пытался определить, печатает ли клиент в поле ввода, это обновит состояние компонента и передаст его соответствующим дочерним компонентам.Я также использую setTimeout здесь, чтобы очистить состояние через 3 секунды.Также не забудьте JSON.parse ответ от веб-сокета.

this.conn.onmessage = e => {
  if (e.data) {
    let data = JSON.parse(e.data);
    if (data.action === 'typing') {
      this.setState({
        isTyping: data.msg
      });
      setTimeout(this.clearIsTyping, 3000);
    }
  }
};

clearIsTyping = () => {
  this.setState({
    isTyping: ''
  });
};
...