[英]Invalid hook call error react-redux hooks
我是 react-redux 的新人,我遇到了問題。 我看了很多網站,但我無法解決這個錯誤。
錯誤文本在這里:
錯誤:無效掛鈎調用。 鈎子只能在 function 組件的內部調用。 這可能由於以下原因之一而發生:
- 您可能有不匹配的 React 版本和渲染器(例如 React DOM)
- 你可能違反了 Hooks 規則
- 你可能在同一個應用程序中有多個 React 副本
這是我的 index.js 文件:
import React from 'react';
import ReactDOM from 'react-dom';
import './index.css';
import App from './App';
import reportWebVitals from './reportWebVitals';
import {Provider} from 'react-redux';
import { createStore } from 'redux'
import all from './reducers/index'
const store = createStore(all)
ReactDOM.render(
<React.StrictMode>
<Provider store ={store}>
<App />
</Provider>
</React.StrictMode>,
document.getElementById('root')
);
reportWebVitals();
這是我的../reducers/index.js 文件:
import {
combineReducers
} from "redux";
import TodoReducer from "./TodoReducer";
import filterReducer from "./filterReducer";
const all = combineReducers({
TodoReducer,
filterReducer,
});
export default all;
filterReducer.js
import { SHOW_ALL, VISIBILITY_FILTER } from "../actions/actionTypes";
const filterReducer = (state = SHOW_ALL, action) => {
switch (action.type) {
case "VISIBILITY_FILTER":
return action.filter;
default:
return state;
}
};
export default filterReducer;
TodoReducer.js
import { ADD_TODO, DELETE_TODO, TOGGLE_TODO } from "../actions/actionTypes";
const TodoReducer = (state = [], action) => {
switch (action.type) {
case "ADD_TODO":
return [
...state, //todos
{
id: action.id,
text: action.text,
completed: false,
},
];
case "TOGGLE_TODO":
return state.map((todo) =>
todo.id === action.id
? {
...todo,
completed: !todo.completed,
}
: todo
);
case "DELETE_TODO":
const numIndex = parseInt(action.id);
return state.filter((todo) => todo.id !== numIndex);
default:
return state;
}
};
export default TodoReducer;
actionTypes.js
export const ADD_TODO = 'ADD_TODO'
export const TOGGLE_TODO = 'TOGGLE_TODO'
export const DELETE_TODO = 'DELETE_TODO'
export const SHOW_ALL = 'SHOW_ALL'
export const VISIBILITY_FILTER = 'VISIBILITY_FILTER'
動作.js
import { ADD_TODO, DELETE_TODO, TOGGLE_TODO, VISIBILITY_FILTER } from './actionTypes'
let TodoId = 0
export const addTodo = text => ({
type: ADD_TODO,
id: TodoId++,
text
})
export const deleteTodo = (id) => ({
type: DELETE_TODO,
id: id
})
export const toggleTodo = (id) => ({
type: TOGGLE_TODO,
id: id
})
export const visibility_filter = filter => ({
type: VISIBILITY_FILTER,
filter
})
這是 Todos.js(這個文件是我使用 hook 的地方):
import React, { useState } from "react";
import { useSelector, useDispatch } from "react-redux";
import { addTodo } from "../actions/actions";
const Todos = () => {
const todos = useSelector((state) => state.todos);
const dispatch = useDispatch();
const onAddTodo = () =>
dispatch(
addTodo(inputText),
todos.map((todo) => <div key={todo.id}>{todo.text}</div>)
);
const [inputText, setInputText] = useState("");
const inputTextHandler = (e) => {
setInputText(e.target.value);
};
return (
<div>
<div className="form-group row">
<div className="col-sm-10">
<input
onChange={inputTextHandler}
value={inputText}
type="text"
className="form-control"
id="inputEmail3"
placeholder="add todo here"
/>
<button
type="button"
onClick={() => setInputText("")}
style={{ marginTop: "25px", marginRight: "15px" }}
className="btn btn-danger"
>
Cancel
</button>
<button
type="button"
onClick={onAddTodo}
style={{ marginTop: "25px" }}
className="btn btn-success"
>
Add Todo
</button>
</div>
</div>
</div>
);
};
export default Todos;
這是 App.js:
import React from "react";
import Table from './components/Table'; // this file is empty for now
import Todos from './components/Todos'
function App() {
return (
<div className="App">
<div className="container" style={{ marginTop: "80px"}} >
<div className="row">
<div className="col-lg-10 offset-lg-2 col-md-10 col-sm-12 col-xs-12">
<Todos />
</div>
<Table />
</div>
</div>
</div>
);
}
export default App;
這是錯誤代碼:
8 | import all from './reducers/index'
9 |
10 | const store = createStore(all,)
> 11 | ReactDOM.render(
12 | <React.StrictMode>
13 | <Provider store ={store}>
14 | <App />
可能有成千上萬的錯誤,我正在努力做出反應,redux 太難了......
問題是什么? 你能幫我嗎? 感謝您的關注。
首先,我想建議切換到使用 redux 的掛鈎,因為它們簡化了一切。
您可以從react-redux
導入useDispatch
和useSelector
而不是connect
,並使用它們(鈎子)來訪問和改變您的 redux state。
例如
import { useSelector, useDispatch } from "react-redux"
import { addTodo } from "../actions/actions"
export const Todo = () => {
//accessing your list of todos
const todos = useSelector(state => state.todos)
//dispatching an action
const dispatch = useDispatch()
const onAddTodo = () => dispatch(addTodo(someData))
return (
<div>
<div className="form-group row">
<div className="col-sm-10">
<input
onChange={inputTextHandler}
value={inputText}
type="text"
className="form-control"
id="inputEmail3"
placeholder="add todo here"
/>
<button
type="button"
onClick={() => setinputText("")}
style={{ marginTop: "25px", marginRight: "15px" }}
className="btn btn-danger"
>
Cancel
</button>
<button
type="button"
onClick={onAddTodo}
style={{ marginTop: "25px" }}
className="btn btn-success"
>
Add Todo
</button>
</div>
</div>
</div>
);
}
一般使用鈎子時,有一點你需要了解,鈎子是在主組件內部聲明的。
您不能在組件的另一個 function 內聲明一個鈎子。
例如
讓我們使用上面的代碼作為示例。 在上面的代碼中,我們定義onAddTodo
function,我們過去常常將一個動作分派給我們的 redux state。我們如何做上面的代碼是正確的,但會有一種情況我們可能會出錯,反應當然會拋出這樣的錯誤你目前面對的那個。
下面是使用鈎子的錯誤方法,因為它是在不是主要組件的 function 內部聲明或啟動的。
const onAddTodo = () => {
//WRONG...
const dispatch = useDispatch()
dispatch(addTodo(someData))
}
查看您的代碼后,我看到了這一點。
<button
type="button"
onClick={(inputText = "")}
style={{ marginTop: "25px", marginRight: "15px" }}
className="btn btn-danger"
>
問題在於:
onClick={(inputText = "")}
組件的 state 只能使用創建 state 時提供的 function 進行更改。在您的情況下,function 稱為setInputText
。
你的按鈕應該是這樣的:
const handleInputReset = () => setInputText('');
<button
type="button"
onClick={handleInputReset}
style={{ marginTop: "25px", marginRight: "15px" }}
className="btn btn-danger"
>
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.