Форум программистов, компьютерный форум, киберфорум
React/ReactJS
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
3 / 3 / 1
Регистрация: 20.02.2018
Сообщений: 126

React Strict mode Socket.io много сообщений

16.01.2023, 10:38. Показов 527. Ответов 4
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
Здравствуйте!!!
Не могу понять как решить проблему с сокетами. У меня при переходе в чат. Появляется 4 сообщения с сервера(Привет, ${user.name}), а мне нужно 1. Если убрать React.StrictMode то сообщение будет 1, но это такое себе решение.

JavaScript
1
2
3
4
5
6
7
8
const root = ReactDOM.createRoot(document.getElementById('root'));
root.render(
  <React.StrictMode>
      <BrowserRouter>
          <App />
      </BrowserRouter>
  </React.StrictMode>
);
React:
JavaScript
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
import {memo, useEffect, useState} from "react";
import { useLocation, useParams } from "react-router-dom";
import queryString from 'query-string';
import EmojiPicker from "emoji-picker-react";
 
// import socket from "../../socket";
 
import icon from "../../images/emoji.svg";
import styles from "../../styles/Chat.module.css";
import {Messages} from "./components";
import {io} from "socket.io-client";
 
const options = {
    // "force new connection": true,
    // reconnectionAttempts: "Infinity",
    // timeout : 10000,
    transports : ["websocket"]
}
 
const socket = io(`http://localhost:3999`, options);
 
export const Chat = () => {
    const params = useParams();
    // const params = queryString.parse(search);
 
    const [isOpen, setIsOpen] = useState(false);
    const [isConnect, setIsConnect] = useState(false);
 
    const [message, setMessage] = useState('');
    const [messages, setMessages] = useState([]);
    const [users, setUsers] = useState(0);
 
    console.log('messages: ', messages);
 
    useEffect(() => {
 
 
        socket.emit('join', params);
 
        socket.on('message', ({ data }) => {
            setMessages((prevMessages) => [...prevMessages, data]);
        });
 
    }, []);
 
    useEffect(() => {
 
    }, []);
 
    const openImojiHandler = () => setIsOpen(!isOpen);
 
    const changeMessageHandler = (e) => setMessage(e.target.value);
 
    const onEmojiClickHandler = ({ emoji }) => setMessage(`${message} ${emoji}`);
 
    const addNewMessageHandler = (e) => {
        e.preventDefault();
 
        if(!message) return;
 
        // socket.emit('sendMessage', { message, params });
 
        setMessage('');
    };
 
    const leftRoomHandler = (e) => {
        e.preventDefault();
    };
 
    return (
        <div className={styles.wrap}>
            <div className={styles.header}>
                <div className={styles.title}>Комната: {params.room}</div>
                <div className={styles.users}>{users} пользователей в комнате</div>
                <button className={styles.left} onClick={leftRoomHandler}>
                    Покинуть комнату
                </button>
            </div>
 
            <div className={styles.messages}>
                <Messages messages={messages} name={params.name} />
            </div>
 
            <form className={styles.form} onSubmit={addNewMessageHandler}>
                <div className={styles.input}>
                    <input
                        type="text"
                        name="message"
                        placeholder="Напишите сообщение"
                        value={message}
                        onChange={changeMessageHandler}
                        autoComplete="off"
                        required
                    />
                </div>
                <div className={styles.emoji}>
                    <img src={icon} alt="" onClick={openImojiHandler} />
 
                    {isOpen && (
                        <div className={styles.emojies}>
                            <EmojiPicker onEmojiClick={onEmojiClickHandler} />
                        </div>
                    )}
                </div>
 
                <div className={styles.button}>
                    <input type="submit" onSubmit={addNewMessageHandler} value="Отправить" />
                </div>
            </form>
        </div>
    );
};
Node:
JavaScript
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
const path = require('path');
const dotenv = require('dotenv');
const cors = require('cors');
const logger = require('morgan');
const express = require('express');
const app = express();
const mongoose = require('mongoose');
const cookieParser = require('cookie-parser');
 
const {addUser} = require("./src/data/users");
 
const indexRoutes = require('./src/routes/index.route');
 
dotenv.config({
    path: path.resolve(__dirname, '.env'),
});
 
const PORT = process.env.PORT || 3078;
 
app.use(cors());
app.use(logger('dev'));
app.use(express.json());
app.use(express.urlencoded({
    extended: true,
}));
app.use(cookieParser());
 
app.use('/api', indexRoutes);
 
const server = require('http').createServer(app);
const io = require('socket.io')(server);
 
// const {version, validate} = require('uuid');
 
 
io.on('connection', (socket) => {
 
    socket.on('join', ({name, room}) => {
        // console.log(name, room);
 
        socket.join(room);
 
        const { user } = addUser({name, room});
 
        socket.emit('message', {
            data: { user: { name: 'Admin'}, message: `Привет, ${user.name}` }
        });
 
        socket.broadcast.to(user.room).emit('message', {
            data: { user: { name: 'Admin'},  message: `Пользователь ${user.name} присоединился` }
        });
 
    });
 
    socket.on('sendMessage', ({ message, params }) => {
 
    });
 
    io.on('disconnect', () => console.log('socket disconnected...'))
});
 
 
server.listen(PORT, () => {
    console.log(`Server started on http://localhost:${PORT}`);
 
    mongoose.connect(
        process.env.MONGO_URL, {
            useNewUrlParser: true,
        },
    ).then(() => {
        console.log('Connection mongodb success!!!');
    }).catch((error) => console.log(error));
});
0
cpp_developer
Эксперт
20123 / 5690 / 1417
Регистрация: 09.04.2010
Сообщений: 22,546
Блог
16.01.2023, 10:38
Ответы с готовыми решениями:

Mobx strict mode
Добрый день, объясните, пожалуйста, почему выходит предупреждение Since strict-mode is enabled, changing (observed) observable values...

SyntaxError: Use of reserved word 'let' in strict mode
Всем привет, есть проблема, ошибка в браузере safari 5.1.4 на винде, и на ipad ios 9.3.5 ошибка &quot;SyntaxError: Use of reserved word...

Различия strict mode в javascript
подскажите для чего используется и чем конкретно отличается strict mode от обычного?

4
Эксперт JSЭксперт HTML/CSS
 Аватар для krvsa
3803 / 1639 / 428
Регистрация: 14.03.2022
Сообщений: 4,080
16.01.2023, 10:55
Цитата Сообщение от riddlejs Посмотреть сообщение
Если убрать React.StrictMode то сообщение будет 1, но это такое себе решение.
Насколько я припоминаю React.StrictMode как раз и вызывает "повышенный рендеринг" компонентов в режиме отладки...

А в рабочем режиме уже такого не будет.
1
3 / 3 / 1
Регистрация: 20.02.2018
Сообщений: 126
16.01.2023, 11:15  [ТС]
Цитата Сообщение от krvsa Посмотреть сообщение
Насколько я припоминаю React.StrictMode как раз и вызывает "повышенный рендеринг" компонентов в режиме отладки...

А в рабочем режиме уже такого не будет.
Ну это конечно не очень как то круто. Я смысл особо не улавливаю от этого.

Добавлено через 12 минут
Таким способом можно с 4 сообщений до 2х сделать) но всеравно 2 не 1но)
JavaScript
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
    useEffect(() => {
 
 
        socket.emit('join', params);
 
        socket.on('message', ({ data }) => {
            setMessages((prevMessages) => [...prevMessages, data]);
        });
 
        return () => {
            socket.off('join');
            socket.off('message');
        };
 
    }, []);
0
Эксперт JSЭксперт HTML/CSS
 Аватар для krvsa
3803 / 1639 / 428
Регистрация: 14.03.2022
Сообщений: 4,080
16.01.2023, 13:01
Цитата Сообщение от riddlejs Посмотреть сообщение
Ну это конечно не очень как то круто. Я смысл особо не улавливаю от этого.
Там проверки всякие добавляются. Вот для этого и рендерят по нескольку раз...

Я особо в смысл не вдавался. Мы просто не используем совсем эту обертку.

Добавлено через 2 минуты
Цитата Сообщение от riddlejs Посмотреть сообщение
Таким способом можно с 4 сообщений до 2х сделать) но всеравно 2 не 1но)
Как рассуждение на эту тему...

Можно завести локальный стейт типа "я уже такое делал". Тогда некое действо запускать только "если ты такого еще не делал" и переводить тот стейт в состояние "я уже это сделал".
Т.о. будет всего один запрос.

Добавлено через 10 минут
riddlejs, сейчас вот почитал про React.StrictMode еще раз...
https://runebook.dev/ru/docs/react/strict-mode

Как одна из рекомендаций в той статье - не вешать React.StrictMode на все приложение. Использовать его только там, где нет (таких) "проблемных" мест.

Сам факт размещения этого кода в useEffect - уже правильный шаг. Поскольку 2 рендера в Реакте это норма.
2
Молодой техлид)
Эксперт JSЭксперт HTML/CSS
 Аватар для mr_dramm
1818 / 1056 / 329
Регистрация: 17.07.2021
Сообщений: 2,146
Записей в блоге: 14
16.01.2023, 17:06
Цитата Сообщение от krvsa Посмотреть сообщение
Я особо в смысл не вдавался. Мы просто не используем совсем эту обертку.
Да все верно они перечислены тут

Для размышления несколько слов...
Многие негодуют зачем были сделаны эти дополнительные монтирования и размонтирования именно так, т.е. как новое поведение Strict Mode. Ответ чатично на это есть в #19 Adding Reusable State to StrictMode. Планируется добавить нвый функционал Offscreen API и еще много нового что будет работать с новым API Concurrent render React 18. Поэтому это было сделано как подготовка компонентов к этому новому, но пока используемого только в режиме разработки. Мейчас это новое API, используется только в React Fast Refresh (пришло на смену webpack HMR) повторно рендерит компоненты в случае внесения изменения в исходные файлы подробнее можно почитать тут, эта функция также работает только в режиме разработки. Каждое изменние в исходных файлах компонента она перезапускает хуки у которых есть зависимости, но сохраняет состояние компонентов в том числе и ref. И ее тоже можно заблочить и смотреть на новые изменения нажимая f5:

например так если используете react scripts смотри настройки тут
Code
1
cross-env FAST_REFRESH=false WDS_SOCKET_HOST=unknown react-scripts start
или если не react scripts то можно FAST_REFRESH=false передать как переменную среды любым бдругим способом
а в webpack.config.json смотри настройки
JavaScript
1
2
3
    devServer: {
     hot: false,
    },
Так что пока ждём чего-то нового в проде и превозмогаем дев режиме
3
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
raxper
Эксперт
30234 / 6612 / 1498
Регистрация: 28.12.2010
Сообщений: 21,154
Блог
16.01.2023, 17:06
Помогаю со студенческими работами здесь

Create-react-app development mode с php
Каким образом можно при разработке ссылаться на бакэнд файлы php? вписать ссылку &quot;./controller/HomeController.php&quot; работает...

Socket Raw Promiscuous mode
Здравствуйте! Решил сделать небольшую программу для подсчета трафика между своими товарищами по работе. Все бы ничего, но если я...

Отправка сообщений socket
Здравствуйте, я делаю TCP чат, мне нужно сделать отправку сообщения к каждому подключению, но когда в дело вступают input, возникают...

Странности с отправкой сообщений. (socket)
Добрый день! Возникла некоторая проблема, дело в том что при отправке сообщений (одного длинного и одного короткого) после 520-580 знака...

Отправка сообщений в комнату Socket io
В комнате присутствует неопределенное количество пользователей, один из них выполняет как-то действие, оно отправляется на сервер, а потом...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
5
Ответ Создать тему
Новые блоги и статьи
Thinkpad X220 Tablet — это лучший бюджетный ноутбук для учёбы, точка.
Programma_Boinc 23.12.2025
Thinkpad X220 Tablet — это лучший бюджетный ноутбук для учёбы, точка. Рецензия / Мнение/ Перевод https:/ / **********/ gallery/ thinkpad-x220-tablet-porn-gzoEAjs . . .
PhpStorm 2025.3: WSL Terminal всегда стартует в ~
and_y87 14.12.2025
PhpStorm 2025. 3: WSL Terminal всегда стартует в ~ (home), игнорируя директорию проекта Симптом: После обновления до PhpStorm 2025. 3 встроенный терминал WSL открывается в домашней директории. . .
Как объединить две одинаковые БД Access с разными данными
VikBal 11.12.2025
Помогите пожалуйста !! Как объединить 2 одинаковые БД Access с разными данными.
Новый ноутбук
volvo 07.12.2025
Всем привет. По скидке в "черную пятницу" взял себе новый ноутбук Lenovo ThinkBook 16 G7 на Амазоне: Ryzen 5 7533HS 64 Gb DDR5 1Tb NVMe 16" Full HD Display Win11 Pro
Музыка, написанная Искусственным Интеллектом
volvo 04.12.2025
Всем привет. Некоторое время назад меня заинтересовало, что уже умеет ИИ в плане написания музыки для песен, и, собственно, исполнения этих самых песен. Стихов у нас много, уже вышли 4 книги, еще 3. . .
От async/await к виртуальным потокам в Python
IndentationError 23.11.2025
Армин Ронахер поставил под сомнение async/ await. Создатель Flask заявляет: цветные функции - провал, виртуальные потоки - решение. Не threading-динозавры, а новое поколение лёгких потоков. Откат?. . .
Поиск "дружественных имён" СОМ портов
Argus19 22.11.2025
Поиск "дружественных имён" СОМ портов На странице: https:/ / norseev. ru/ 2018/ 01/ 04/ comportlist_windows/ нашёл схожую тему. Там приведён код на С++, который показывает только имена СОМ портов, типа,. . .
Сколько Государство потратило денег на меня, обеспечивая инсулином.
Programma_Boinc 20.11.2025
Сколько Государство потратило денег на меня, обеспечивая инсулином. Вот решила сделать интересный приблизительный подсчет, сколько государство потратило на меня денег на покупку инсулинов. . . .
Ломающие изменения в C#.NStar Alpha
Etyuhibosecyu 20.11.2025
Уже можно не только тестировать, но и пользоваться C#. NStar - писать оконные приложения, содержащие надписи, кнопки, текстовые поля и даже изображения, например, моя игра "Три в ряд" написана на этом. . .
Мысли в слух
kumehtar 18.11.2025
Кстати, совсем недавно имел разговор на тему медитаций с людьми. И обнаружил, что они вообще не понимают что такое медитация и зачем она нужна. Самые базовые вещи. Для них это - когда просто люди. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2025, CyberForum.ru