无效的挂钩调用错误反应冗余挂钩



我是react redux的新手,遇到了一个问题。我看了很多网站,但我无法解决这个错误。

错误文本在这里:

错误:钩子调用无效。钩子只能称为身体内部功能组件。以下情况之一可能会发生这种情况原因:

  1. React和渲染器的版本可能不匹配(例如React DOM)
  2. 你可能违反了胡克规则
  3. 同一应用程序中可能有多个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'

actions.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(这个文件是我使用钩子的地方):

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的钩子,因为它们简化了一切。

您可以从react-redux导入useDispatchuseSelector,而不是connect,并使用它们(钩子)来访问和更改您的redux状态。

E.g


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

一般使用钩子时,需要了解的是,钩子是在主组件内部声明的。

不能在组件的另一个函数中声明钩子。

E.g

让我们将上面的代码用于我们的示例。在上面的代码中,我们定义了onAddTodo函数,用于将操作调度到我们的redux状态。我们执行上述代码的方式是正确的,但在某些情况下,我们可能会出错,做出反应当然会给我们带来一个错误,就像您目前面临的错误一样。

以下是使用钩子的错误方法,因为它是在非主要组件的函数内部声明或启动的。

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

只有使用创建状态时提供的功能才能更改组件的状态。在您的情况下,该函数称为setInputText

你的按钮应该是这样的:

const handleInputReset = () => setInputText('');
<button
type="button"
onClick={handleInputReset}
style={{ marginTop: "25px", marginRight: "15px" }}
className="btn btn-danger"
>

参考:https://reactjs.org/docs/hooks-state.html

相关内容

  • 没有找到相关文章

最新更新