Larry Schwall
Larry Schwall

Reputation: 23

How to prevent a re-render with a functional component and react hooks?

Issue: Web Application re-rendering with input onChange event, thus causing socket to disconnect then reconnect.

Detail: I am creating a small multiplayer game with Socket.io, React, Express, PostgreSql, and Nodejs. I would like the user to be able to search for a room name with an input box and a submit button or create a game with a button.

Question: Is there a way to prevent a re-render when the user inputs the room code in the input box?


Code:

App.js

const App = () => {
    const socket = io();
    const [roomCode, setRoomCode] = useState('');

        // CREATE ROOM CODE
    const createRoom = () => {
        socket.emit('create', true)
        socket.once('roomCreated', room => {
            axios.post(`/room/roomCode?room=${room}`)
                .then(({ data }) => {
                    console.log(data);
                })
                .catch(err => console.warn(err))
        })
    }

        // JOIN SPECIFIC ROOM
    const joinRoom = () => {
        axios.post(`/room/findRoom?roomCode=${roomCode}`)
            .then(({ response }) => {
                console.info(response)
            })
            .catch(err => console.warn(err))
    }

    return (
        <div>
            <button
                onClick={createRoom}
            >
                Create
            </button>
            <input
                placeholder="Room Code"
                onChange={(e) => { setRoomCode(e.target.value) }}
            />
            <button onClick={joinRoom}>
                Enter Room Code
            </button>
        </div>
    )
}

Room.js route

roomRouter.post('/findRoom', (req, res) => {
    const { roomCode } = req.query
    Room.findOne({
        where: {
            room_code: roomCode,
        }
    })
        .then(room => {
            room ? res.send(room) : res.send('room does not exist')
        })
        .catch(err => console.warn(err))
})

Upvotes: 1

Views: 695

Answers (2)

Alen.Toma
Alen.Toma

Reputation: 4870

changing your socket declaration to

 const [socket] = useState(io());

should fix the issue.

Or simple move it outside the component

Upvotes: 1

Ryan
Ryan

Reputation: 1050

Each time state changes, the entire component is re-rendered, including your first line const socket = io(). Try moving that line on top of your component like so:

const socket = io()

const App = () => {
  // ...
}

Upvotes: 1

Related Questions