用React.js设置useContext和useState的正确方法?

时间:2020-05-03 18:45:57

标签: reactjs react-native react-hooks

我有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 }

然后在我的组件RoomPage.tsx中,我拥有:

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>
    )
}

但是我收到关于setRoomState的投诉:

This expression is not callable.
  Type '{}' has no call signatures.

1 个答案:

答案 0 :(得分:1)

这里的问题是,您试图在没有RoomContext的组件(RoomPage)中使用RoomContext.Provider,该组件在层次结构中较高,因为它是在组件中呈现的。

这里的解决方案是用RoomProvider包裹RoomPage

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>
)