繁体   English   中英

Function 作为道具传递,而不是 function

[英]Function passed as props not a function

我试图通过一个名为 addtodo 的 function 作为 class 的道具。 我已经通过了 function 如下

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 中,我使用 function 作为道具,如下所示

 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 我也检查了拼写错误,但不明白为什么这不起作用。 而如果我将它作为道具传递给另一个 class 并简单地记录一个它正在工作的 hello 消息。

我在 stackblitz 上成功运行了你的代码,没有错误

我发现了另一个错误,

handleChange(e) {
    this.setState({
      [e.target.id]: [e.target.value]
    });
  }

handleChange(e) {
    this.setState({
      [e.target.id]: e.target.value
    });
  }

检查 stackblitz 演示

提示:因为我的积分不够,所以不能加评论,只能编辑回答

更新:

前:

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?

You're not registering the function addtodo in the class, thus this.addtodo is not bound to your function addtodo but instead to null. 因此你的错误。

请参阅React 文档中的此示例 - 处理事件

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 行 function 首先绑定到 class,然后可以通过this.<function_name>定义和调用它。

在您的代码中,您在构造函数中缺少:

this.addtodo = this.addtodo.bind(this);

在此之前,您不能调用this.addtodo ,因为它没有绑定到this ,因此您的错误是this.props.addtodo不是 function。

我猜你的构造函数中缺少绑定。 在您的构造函数中,您需要像这样声明它

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;

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM