我正在尝试将名为addtodo的函数作为类的道具传递。我已经通过了如下功能
export class Todo extends Component {
constructor(props) {
super(props);
this.state = {todos:[]};
this.addtodo = this.addtodo.bind(this);
this.deleteTodo = this.deleteTodo.bind(this);
}
componentDidMount(){
axios.get('https://jsonplaceholder.typicode.com/posts').then(res=>{
this.setState({
todos:res.data
})
})
}
addtodo(todo){
todo.id=Math.floor(Math.random()*100)
todo.completed=true
const todos=[...this.state.todos,todo]
this.setState({
todos:todos
})
}
deleteTodo(id){
const todo=this.state.todos.filter(todo=>{
return(
todo.id!==id
)
}
)
this.setState({
todos:todo
})
}
render() {
return (
<div>
<h1 className="center-align"> Todos</h1>
<Todolist todos={this.state.todos} deleteTodo={this.deleteTodo}/>
<Addtodo addtodo={this.addtodo}/>
</div>
)
}
}
export default Todo
在Addtodo.js中,我正在使用以下功能作为道具
class Addtodo extends Component {
constructor(props) {
super(props);
this.state = { title:'',
body:''
};
this.handleChange = this.handleChange.bind(this);
this.handleSubmit = this.handleSubmit.bind(this);
}
handleChange(e){
this.setState({
[e.target.id]:[e.target.value]
})
}
handleSubmit(e){
e.preventDefault()
this.props.addtodo(this.state)
this.setState({
title:'',
body:''
})
}
render() {
return (
<form className="col s12" onSubmit={this.handleSubmit}>
<div className="row">
<div className="input-field col s6">
<input placeholder="Add title" id="title" type="text" className="validate" onChange={this.handleChange}/>
</div>
<div className="input-field col s6">
<input placeholder="Add body" id="body" type="text" className="validate" onChange={this.handleChange}/>
</div>
<button type="submit">Submit</button>
</div>
</form>
)
}
}
export default Addtodo
但是我收到错误Uncaught TypeError: this.props.addtodo is not a function
。我也检查了拼写错误,但无法弄清为什么它不起作用。而如果我将它作为道具传递给另一个类,并简单地记录一个问候消息,则它正在工作。
答案 0 :(得分:1)
我成功地在stackblitz上运行了您的代码,并且没有错误
我发现了另一个错误,
之前
handleChange(e) {
this.setState({
[e.target.id]: [e.target.value]
});
}
之后
handleChange(e) {
this.setState({
[e.target.id]: e.target.value
});
}
提示: 因为我没有足够的分数,所以我无法添加评论,只能由编辑者回答
更新:
之前:
function App() {
return (
<BrowserRouter>
<div className="container">
<Addtodo />
<Switch>
<Route exact path="/" component={Todo} />
<Route path="/:id" component={Task} />
</Switch>
</div>
</BrowserRouter>
);
}
export default App;
function App() {
return (
<BrowserRouter>
<div className="container">
<Switch>
<Route exact path="/" component={Todo} />
</Switch>
</div>
</BrowserRouter>
);
}
render(<App/>, document.getElementById('root'))
请检查代码不超过一个Addtodo吗?
答案 1 :(得分:0)
您没有在类中注册函数addtodo
,因此this.addtodo
未绑定到函数addtodo
而是为空。因此,您的错误。
请参见React docs - Handling events中的示例:
class Toggle extends React.Component {
constructor(props) {
super(props);
this.state = {isToggleOn: true};
// This binding is necessary to make `this` work in the callback
this.handleClick = this.handleClick.bind(this);
}
handleClick() {
this.setState(state => ({
isToggleOn: !state.isToggleOn
}));
}
render() {
return (
<button onClick={this.handleClick}>
{this.state.isToggleOn ? 'ON' : 'OFF'}
</button>
);
}
}
ReactDOM.render(
<Toggle />,
document.getElementById('root')
);
第6行注意,该函数首先绑定到该类,然后可以通过this.<function_name>
对其进行定义和调用。
在您的代码中,构造函数不见了:
this.addtodo = this.addtodo.bind(this);
在此之前,您无法调用this.addtodo
,因为它没有绑定到this
,因此您的错误是this.props.addtodo
不是函数。
答案 2 :(得分:0)
我猜你在构造函数中缺少绑定。在您的构造函数中,您需要像这样声明它
this.addtodo = this.addtodo.bind(this);
已编辑**
我已经测试了代码,似乎没有错误,
Todo.js
import React, { Component } from "react";
import axios from "axios";
import Addtodo from "./Addtodo";
export class Todo extends Component {
state = {
todos: [],
};
componentDidMount() {
axios.get("https://jsonplaceholder.typicode.com/posts").then((res) => {
this.setState({
todos: res.data,
});
});
}
addtodo = (todo) => {
todo.id = Math.floor(Math.random() * 100);
todo.completed = true;
const todos = [...this.state.todos, todo];
this.setState({
todos: todos,
});
};
render() {
console.log(this.state.todos);
return (
<div>
<h1 className="center-align"> Todos</h1>
<Addtodo addtodo={this.addtodo} />
</div>
);
}
}
export default Todo;
Addtodo.js
import React, { Component } from "react";
class Addtodo extends Component {
constructor(props) {
super(props);
this.state = { title: "", body: "" };
this.handleChange = this.handleChange.bind(this);
this.handleSubmit = this.handleSubmit.bind(this);
}
handleChange(e) {
this.setState({
[e.target.id]: [e.target.value],
});
}
handleSubmit(e) {
e.preventDefault();
this.props.addtodo(this.state);
this.setState({
title: "",
body: "",
});
}
render() {
return (
<form className="col s12" onSubmit={this.handleSubmit}>
<div className="row">
<div className="input-field col s6">
<input
placeholder="Add title"
id="title"
type="text"
className="validate"
onChange={this.handleChange}
/>
</div>
<div className="input-field col s6">
<input
placeholder="Add body"
id="body"
type="text"
className="validate"
onChange={this.handleChange}
/>
</div>
<button type="submit">Submit</button>
</div>
</form>
);
}
}
export default Addtodo;