我有一个简单的应用程序来反应,当我的 app.js 是一个类组件时,一切都很好,但是当我将它更改为功能组件时发生错误 = todos.filter is not a function
我的文件:Todo.js(函数式) --> TodoList.js(函数式) --> app.js(函数式)
function TodoList(props) {
const [statusDone, setDone] = useState(false);
let { todos } = props;
console.log(todos);
let filterTodos = todos.filter((item) => item.done === statusDone);
return (
<>
<nav className="col-6 mb-3">
<div className="nav nav-tabs" id="nav-tab" role="tablist">
<a
className={`nav-item nav-link font-weight-bold ${
!statusDone ? "active" : ""
}`}
id="nav-home-tab"
onClick={() => setDone(false)}
>
undone{" "}
<span className="badge badge-secondary">
{todos.filter((item) => item.done === false).length}
</span>
</a>
<a
className={`nav-item nav-link font-weight-bold ${
statusDone ? "active" : ""
}`}
id="nav-profile-tab"
onClick={() => setDone(true)}
>
done{" "}
<span className="badge badge-success">
{todos.filter((item) => item.done === true).length}
</span>
</a>
</div>
</nav>
{filterTodos.length === 0 ? (
<p>there isn`t any todos</p>
) : (
filterTodos.map((item) => (
<Todo
key={item.key}
item={item}
delete={props.delete}
done={props.done}
edit={props.edit}
/>
))
)}
</>
);
}
<块引用>
主应用类
function App() {
const [todos, settodos] = useState([]);
let addTo = (text) => {
settodos((prevState) => {
return {
todos: [prevState.todos, { key: Date.now(), done: false, text }],
};
});
};
return (
<div className="App">
<main>
<section className="jumbotron">
<div className="container d-flex flex-column align-items-center">
<h1 className="jumbotron-heading">Welcome!</h1>
<p className="lead text-muted">
To get started, add some items to your list:
</p>
<FormAddTodo add={addTo} />
</div>
</section>
<div className="todosList">
<div className="container">
<div className="d-flex flex-column align-items-center ">
<TodoList
todos={todos}
// delete={this.deleteTodo.bind(this)}
// done={this.toggleTodo.bind(this)}
// edit={this.editTodo.bind(this)}
/>
</div>
</div>
</div>
</main>
</div>
);
}
<块引用>
我试过了
let filterTodos =Object.values(todos).filter(item => item.done === statusDone)
错误已修复,但我的代码无法正常工作
我希望你明白我说的话:)
<块引用>此功能组件用于添加待办事项
function FormAddTodo(props) {
const [text, setText] = useState("");
let formHandler = (e) => {
e.preventDefault();
props.add(text);
setText("");
};
let inputHandler = (e) => setText(e.target.value);
return (
<form className="form-inline mb-5" onSubmit={formHandler}>
<div className="row form-group">
<div className="col-8">
<input
type="text"
className=" form-control mx-sm-3"
placeholder="i want to do ..."
value={text}
onChange={inputHandler}
/>
</div>
<div className="col-4">
<button type="submit" className=" btn btn-primary">
add
</button>
</div>
</div>
</form>
);
}
答案 0 :(得分:1)
问题出在 addTo
函数上。您不是将元素添加到 todos
数组,而是将 todos
设置为一个对象,其键名为 todos,其中包含一个数组。尝试以这种方式修改 addTo
函数:
const addTo = (text) => {
let newElement = { key: Date.now(), done: false, text: text };
settodos(prevState => [...prevState, newElement]);
};
答案 1 :(得分:1)
这里有一个错误:
function App() {
const [todos, settodos] = useState([]);
let addTo = (text) => {
settodos((prevState) => {
return {
todos: [prevState.todos, { key: Date.now(), done: false, text }],
};
});
};
您在 settodos
中的变异函数可以尝试将 prevState.todos 与新的待办事项连接起来。
实际上使用 useState setter,您可以直接获取值:
settodos(currentTodos => ...)
然后返回你想要的值(你返回一个对象而不是一个数组)
此外,如果您想连接两个数组,请使用扩展运算符:
const newArray = [...someArray, newValue];
总而言之,这是一段代码的固定版本:
function App() {
const [todos, settodos] = useState([]);
let addTo = (text) => {
settodos((prevTodos) => [
...prevTodos,
{ key: Date.now(), done: false, text }
]);
};