我正在嘗試構建我的第一個 react 應用程式,并且我正在關注一些標準庫及其快速入門指南,但是對于react-reduxand @reduxjs/toolkit,我無法弄清楚為什么它首先會顯示這個錯誤:
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/link/invalid-hook-call for tips about how to debug and fix this problem.
相關檔案:
../../redux/stateSlices/user.slice
import { createSlice } from "@reduxjs/toolkit";
export const userSlice = createSlice({
name: "user",
initialState: {
loggedInUser: null
},
reducers: {
logToConsole: (state, action) => {
console.log("tryout", state, action.payload);
}
}
});
export const {
logToConsole
} = userSlice.actions;
export default userSlice.reducer;
../../redux/store
import { configureStore } from '@reduxjs/toolkit';
import userReducer from './stateSlices/user.slice';
export const store = configureStore({
reducer: {
user: userReducer
}
});
./pages/register/register
import React, { useState } from 'react'
import {
signIn,
createUser,
deleteUser
} from '../../services/user.service';
import { useDispatch, useSelector } from 'react-redux';
import { Navigate, Link } from 'react-router-dom';
import {
logToConsole
} from '../../redux/stateSlices/user.slice';
export function Register() {
const [errorMessage, setErrorMessage] = useState('');
const [Username, setUsername] = useState('');
const [MailAddress, setMailAddress] = useState('');
const [Password, setPassword] = useState('');
const [Name, setName] = useState('');
const [Surname, setSurname] = useState('');
const dispatch = useDispatch();
const user = useSelector((state) => state.loggedInUser);
const RegisterUser = (e) =>
{
e.preventDefault();
try
{
console.log("user", user);
if(/^\w ([\.-]?\w )*@\w ([\.-]?\w )*(\.\w{2,3}) $/.test(MailAddress))
{
var createUserResponse = createUser(
Username,
MailAddress,
Name,
Surname,
Password,
Username === 'admin' ? 999999999 : 0
);
if(createUserResponse.Status)
{
dispatch(logToConsole(1));
Navigate({ to: "/" });
}
else
{
if(createUserResponse.ErrorList)
{
setErrorMessage(createUserResponse.ErrorList.join(','));
}
else
{
setErrorMessage("Kay?t i?lemi s?ras?nda beklenmedik bir hata ya?and?, daha sonra tekrar deneyiniz.");
}
}
}
else
{
setErrorMessage("Ge?ersiz mail adresi.");
}
}
catch(err)
{
if(err.code === 'duplicateValue')
{
setErrorMessage(err.ErrorList.join(','));
}
else
{
deleteUser(MailAddress);
setErrorMessage(err.message);
}
}
}
return (
<div className="login-page">
<div className='container d-flex align-items-center'>
<div className='form-holder has-shadow'>
<div className="row">
<div class="col-lg-6">
<div class="info d-flex align-items-center">
<div class="content">
<div class="logo">
<h1>appName</h1>
</div>
</div>
</div>
</div>
<div class="col-lg-6 bg-white">
<div class="form d-flex align-items-center">
<div class="content">
<div className="col-12 text-white ff-arial text-center"><h3>Kaydol</h3></div>
{
errorMessage &&
<span className='col-12 text-white pl-0 pb-3 m-0'> { errorMessage } </span>
}
<div class="form-group">
<input
id="login-name"
type="text"
name="loginName"
required
data-msg="Lütfen ad?n?z? adresinizi eksiksiz bir ?ekilde giriniz."
class="input-material"
value={Name}
onChange={(e) => setName(e.target.value)}/>
<label for="login-name" class="label-material">Ad</label>
</div>
<div class="form-group">
<input
id="login-surname"
type="text"
name="loginSurname"
required
data-msg="Lütfen soyad?n?z? adresinizi eksiksiz bir ?ekilde giriniz."
class="input-material"
value={Surname}
onChange={(e) => setSurname(e.target.value)}/>
<label for="login-surname" class="label-material">Soyad</label>
</div>
<div class="form-group">
<input
id="login-userName"
type="text"
name="loginUsername"
required
data-msg="Lütfen kullan?c? ad?n?z? adresinizi eksiksiz bir ?ekilde giriniz."
class="input-material"
value={Username}
onChange={(e) => setUsername(e.target.value)}/>
<label for="login-userName" class="label-material">Kullan?c? ad?</label>
</div>
<div class="form-group">
<input
id="login-mail"
type="text"
name="loginMailAddress"
required
data-msg="Lütfen e-mail adresinizi eksiksiz bir ?ekilde giriniz."
class="input-material"
value={MailAddress}
onChange={(e) => setMailAddress(e.target.value)}/>
<label for="login-mail" class="label-material">Mail Adresi</label>
</div>
<div class="form-group">
<input
id="login-password"
type="password"
name="loginPassword"
required
data-msg="?ifrenizi eksiksiz olarak giriniz."
class="input-material"
value={Password}
onChange={(e) => setPassword(e.target.value)}/>
<label for="login-password" class="label-material">?ifre</label>
</div>
<button className='btn btn-block btn-primary' onClick={(e) => RegisterUser(e)}>Kaydol</button>
<div className="col-12 mt-3 text-center text-white">
<span>veya <Link to="/login" className='ml-1'>Giri? Yap</Link></span>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
)
}
index.js
import React from 'react';
import ReactDOM from 'react-dom/client';
import './index.css';
import App from './App';
import reportWebVitals from './reportWebVitals';
import {
BrowserRouter,
Routes,
Route
} from 'react-router-dom';
import { store } from './redux/store';
import { Provider } from 'react-redux';
import { Register } from './pages/register/register';
const root = ReactDOM.createRoot(document.getElementById('root'));
root.render(
<Provider store={store}>
<BrowserRouter>
<Routes>
<Route path='/' element={<App/>}>
<Route path='/' element={<Index/>}></Route>
</Route>
<Route path='register' element={<Register/>} ></Route>
</Routes>
</BrowserRouter>
</Provider>
);
// If you want to start measuring performance in your app, pass a function
// to log results (for example: reportWebVitals(console.log))
// or send to an analytics endpoint.
package.json
{
"name": "appName",
"version": "0.1.0",
"private": true,
"dependencies": {
"@reduxjs/toolkit": "^1.8.2",
"@testing-library/jest-dom": "^5.16.4",
"@testing-library/react": "^13.2.0",
"@testing-library/user-event": "^13.5.0",
"i": "^0.3.7",
"react-redux": "^8.0.2",
"react-router": "^6.3.0",
"react-router-dom": "^6.3.0",
"react-scripts": "5.0.1",
"redux": "^4.2.0",
"web-vitals": "^2.1.4"
},
"peerDependencies": {
"react": "^18.1.0",
"react-dom": "^18.1.0"
},
"scripts": {
"start": "react-scripts start",
"build": "react-scripts build",
"test": "react-scripts test",
"eject": "react-scripts eject"
},
"eslintConfig": {
"extends": [
"react-app",
"react-app/jest"
]
},
"browserslist": {
"production": [
">0.2%",
"not dead",
"not op_mini all"
],
"development": [
"last 1 chrome version",
"last 1 firefox version",
"last 1 safari version"
]
},
"devDependencies": {
"eslint-plugin-react-hooks": "^4.5.0"
}
}
對于register.js檔案,當我像這樣直接添加dispatch()方法時button.onClick,它不會給出錯誤:
<button className='btn btn-block btn-primary' onClick={(e) => dispatch(logToConsole(1))}>Kaydol</button>
但我需要dispatch在我的自定義函式中使用該方法,如他們的快速入門指南所示。
我試過這個,但沒有用。另外,據我所知,我在功能組件中使用它。
我在這里做錯了什么?
uj5u.com熱心網友回復:
您的錯誤是由此引起的
Navigate({ to: "/" });
這是不正確的使用方式Navigate。我認為根據您的代碼,您想改用useNavigate()鉤子
您的 redux 也不正確(不會導致您的錯誤,但是...)
const user = useSelector((state) => state.loggedInUser);
user 總是未定義的,因為在你的 reducer 中你沒有一個名為loggedInUser你的狀態,你只有user指向你的 userReducer。
這應該給你你想要的:
const user = useSelector((state) => state.user.loggedInUser);
轉載請註明出處,本文鏈接:https://www.uj5u.com/net/482163.html
