'retrieve store data from react redux
I'm new to redux, I can't get data from the store.I get this message in the console: Error: 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:
- You might have mismatching versions of React and the renderer (such as React DOM)
- You might be breaking the Rules of Hooks
- You might have more than one copy of React in the same app See https://reactjs.org/link/invalid-hook-call for tips about how to debug and fix this problem.
thank you in advance for help.
reducer
import { CONNECT_CLIENT, GET_CLIENT } from "../action/Action";
export const initialClient = {
email: "",
password: ""
}
export default function ConnectClient (state = initialClient, action= {}){
switch (action.type) {
case CONNECT_CLIENT:
console.log(action.payload);
return {
...state,
client: [action.payload]
}
case GET_CLIENT:
return {
...state,
initialClient: action.initialClient
}
default:
break;
}
}
clientService
export const ConnectClient = () =>{
const {initialClient } = useSelector(state => state)
console.log(initialClient)
const dispatch = useDispatch();
dispatch({
type: GET_CLIENT,
initialClient: initialClient
})
return new Promise((resolve, reject)=>{
axios.post('http://localhost:3000/api/client/loginClient',{
initialClient: initialClient
})
.then((response, error)=>{
if(!response || error) {
return reject(`Response rejected: ${error}`);
}
resolve(response);
})
})
}
Form connection
const Connexion = () =>{
const dispatch = useDispatch();
const [email, setEmail] = useState("")
const [password, setPassword] =useState("")
const submit=(e)=>{
e.preventDefault();
ConnectClient().then(response => console.log(response))
console.log(email)
console.log(password)
dispatch({
type: CONNECT_CLIENT,
payload: {email, password}
})
}
return (
<form className="container-connexion" model="client">
<div className="container-email-password">
<div className="email">
<label htmlFor="email">Email</label>
<input id="email" type="email" value={email} onChange={(e)=> setEmail(e.target.value)} name="email" required/>
</div>
<div className="password">
<label htmlFor="password">Mot de passe</label>
<input type="password" value={password} name="password" onChange={(e)=> setPassword(e.target.value)} required/>
</div>
</div>
<div className="container-btn-connexion">
<button className="btn-connexion" onClick={submit} >Se connecter</button>
<button className="btn-inscription">Inscription</button>
</div>
</form>
)
}
Solution 1:[1]
We can only call hooks inside the body of functional components, or in the body of custom hooks. Your ConnectClient function is neither of those.
One solution is calling the useDispatch and useSelector hooks in the Connexion component, and passing initialClient and dispatch to the ConnectClient function as parameters.
export const ConnectClient = (dispatch, initialClient) => {
dispatch({
type: GET_CLIENT,
initialClient: initialClient,
});
return new Promise((resolve, reject) => {
axios.post('http://localhost:3000/api/client/loginClient', {
initialClient: initialClient,
}).then((response, error) => {
if(!response || error) {
return reject(`Response rejected: ${error}`);
}
resolve(response);
});
});
};
const Connexion = () =>{
const dispatch = useDispatch();
const [email, setEmail] = useState("");
const [password, setPassword] = useState("");
const { initialClient } = useSelector(state => state);
const submit=(e)=>{
e.preventDefault();
ConnectClient(dispatch, initialClient).then(response => console.log(response));
dispatch({
type: CONNECT_CLIENT,
payload: {email, password}
})
}
return (
<form className="container-connexion" model="client">
<div className="container-email-password">
<div className="email">
<label htmlFor="email">Email</label>
<input id="email" type="email" value={email} onChange={(e)=> setEmail(e.target.value)} name="email" required/>
</div>
<div className="password">
<label htmlFor="password">Mot de passe</label>
<input type="password" value={password} name="password" onChange={(e)=> setPassword(e.target.value)} required/>
</div>
</div>
<div className="container-btn-connexion">
<button className="btn-connexion" onClick={submit} >Se connecter</button>
<button className="btn-inscription">Inscription</button>
</div>
</form>
);
}
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
Solution | Source |
---|---|
Solution 1 | Szabó Sebestyén |