Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Proper way to setup useContext and useState with React.js?

I have contexts/RoomContext.tsx:

import { useState, createContext } from 'react';

const RoomContext = createContext([{}, () => {}]);

const RoomProvider = (props) => {
    const [roomState, setRoomState] = useState({ meetingSession: null, meetingResponse: {}, attendeeResponse: {} })

    return <RoomContext.Provider value={[roomState, setRoomState]}>
        {props.children}
    </RoomContext.Provider>
}
export { RoomContext, RoomProvider }

Then in my component, RoomPage.tsx, I have:

const RoomPageComponent = (props) => {
    const router = useRouter()
    const [roomState, setRoomState] = useContext(RoomContext);

    useEffect(() => {
        const createRoom = async () => {
            const roomRes = await axios.post('http://localhost:3001/live')
            console.log('roomRes', roomRes)
            setRoomState(state => ({ ...state, ...roomRes.data }))
        }

        if (router.query?.id) {
            createRoom()
        }

    }, [router])

    return <RoomPageWeb {...props} />
}

export default function RoomPage(props) {

    return (
        <RoomProvider>
            <RoomPageComponent {...props} />
        </RoomProvider>
    )
}

But I get a complaint about the setRoomState:

This expression is not callable.
  Type '{}' has no call signatures.
like image 440
Shamoon Avatar asked Jan 19 '26 19:01

Shamoon


1 Answers

The issue here is that you are trying to use RoomContext in a component(RoomPage) which doesn't have RoomContext.Provider, higher up in the hierarchy since it is rendered within the component.

The solution here to wrap RoomPage with RoomProvider

import { RoomProvider, RoomContext } from '../../contexts/RoomContext'
function RoomPage(props) {
    const [roomState, setRoomState] = useContext(RoomContext);

    useEffect(() => {
        const createRoom = async () => {
            const roomRes = await axios.post('http://localhost:3001/live')
            console.log('roomRes', roomRes)
            setRoomState(state => ({...state, ...roomRes.data}))

        }
    ...

    return (

            <RoomPageWeb {...props} />
    )

export default (props) => (
    <RoomProvider><RoomPage {...props} /></RoomProvider>
)
like image 122
Shubham Khatri Avatar answered Jan 21 '26 10:01

Shubham Khatri