I'm trying to port from class component
to react hooks
with Context API
, and I can't figure out what is the specific reason of getting the error.
First, my Codes:
// contexts/sample.jsx
import React, { createContext, useState, useContext } from 'react'
const SampleCtx = createContext()
const SampleProvider = (props) => {
const [ value, setValue ] = useState('Default Value')
const sampleContext = { value, setValue }
return (
<SampleCtx.Provider value={sampleContext}>
{props.children}
</SampleCtx.Provider>
)
}
const useSample = (WrappedComponent) => {
const sampleCtx = useContext(SampleCtx)
return (
<SampleProvider>
<WrappedComponent
value={sampleCtx.value}
setValue={sampleCtx.setValue} />
</SampleProvider>
)
}
export {
useSample
}
// Sends.jsx
import React, { Component, useState, useEffect } from 'react'
import { useSample } from '../contexts/sample.jsx'
const Sends = (props) => {
const [input, setInput ] = useState('')
const handleChange = (e) => {
setInput(e.target.value)
}
const handleSubmit = (e) => {
e.preventDefault()
props.setValue(input)
}
useEffect(() => {
setInput(props.value)
}, props.value)
return (
<form onSubmit={handleSubmit}>
<input value={input} onChange={handleChange} />
<button type="submit">Submit</button>
</form>
)
}
Error I got:
Invariant Violation: Invalid hook call. Hooks can only be called inside of the body of a function component. This could happen for one of the following reasons: 1. You might have mismatching versions of React and the renderer (such as React DOM) 2. You might be breaking the Rules of Hooks 3. You might have more than one copy of React in the same app See https://reactjs.org/warnings/invalid-hook-call-warning.html for tips about how to debug and fix this problem.
Explanation for my code:
I used Context API
to manage the states, and previously I used class component
s to make the views. I hope the structure is straightforward that it doesn't need any more details.
I thought it should work as well, the <Sends />
component gets passed into useSample
HoC function, and it gets wrapped with <SampleProvider>
component of sample.jsx
, so that <Sends />
can use the props
provided by the SampleCtx
context. But the result is failure.
Is it not valid to use the HoC
pattern with React hooks
? Or is it invalid to hand the mutation function(i.e. setValue
made by useState()
) to other components through props
? Or, is it not valid to put 2 or more function components
using hooks
in a single file? Please correct me what is the specific reason.
<Consumer />
because I wanted to useuseContext
instead. Do I have to use<Consumer />
even if I use theuseContext
hook? – AerodyneuseContext()
and<Consumer />
are equivalent. – Soldierly