调用作为prop传递的函数,无论

时间:2018-11-30 19:52:52

标签: reactjs react-props

我正在开发具有以下组件层次结构的应用程序(由ProReact提供)

KanbanContainer => KanbanBoard =>列表=>卡=>核对表

KanbanContainer包含需要向下传递到CheckList组件的方法(因为该组件具有所有ui控件)。看板容器中的方法定义如下

class KanbanBoardContainer extends Component {
  state = { cards: [] };

  componentDidMount() {
    this.setState({ cards: API.getTasks() });
  }
  addTask = (cardId, taskName) => {
    console.log(taskName, " invoked for cardId =", cardId);
  };
  deleteTask = (cardId, taskId, taskIndex) => {
    console.log("deleteTask invoked for cardId = ", cardId);
  };
  toggleTask = (cardId, taskId, taskIndex) => {
    console.log("toggleTask invoked fpr cardId = ", cardId);
  };

  render() {
    return (
      <KanbanBoard
        cards={this.state.cards}
        taskCallbacks={{
          toggleTask: this.toggleTask,
          addTask: this.addTask,
          deleteTask: this.deleteTask
        }}
      />
    );
  }
}

在所有其他组件中,taskCallbacks只是通过props传递。例如:

class List extends React.Component {
  render() {
    let cards = this.props.cards.map(c => {
      return (
        <Card
          id={c.id}
          key={c.id}
          title={c.title}
          description={c.description}
          color={c.color}
          tasks={c.tasks}
          taskCallbacks={this.props.taskCallbacks}
        />
      );
    });

    return (
      <div className="list">
        <h1>{this.props.title}</h1>
        {cards}
      </div>
    );
  }
}

在最后一个组件中,通过prop传递的函数将附加到ui控件,例如复选框和链接。

class CheckList extends Component {
  checkInputKeyPress = event => {
    if (event.key === "Enter") {
      this.props.taskCallbacks.addTask(this.props.cardId, event.target.value);
      event.target.value = "";
    }
  };
  render() {
    const { deleteTask, toggleTask } = this.props.taskCallbacks;
    let tasks = this.props.tasks.map((t, index) => (
      <li key={t.id}>
        <input
          type="checkbox"
          name=""
          id=""
          defaultChecked={t.done}
          onChange={toggleTask(this.props.cardId, t.id, index)}
        />{" "}
        {t.name}{" "}
        <a
          href="#"
          onClick={deleteTask(this.props.cardId, t.id, index)}
        />
      </li>
    ));
    return (
      <div>
        <ul>{tasks}</ul>
        <input
          type="text"
          placeholder="Key in a task and hit enter"
          onKeyPress={this.checkInputKeyPress}
        />
      </div>
    );
  }
}

但是,当我加载应用程序时,这些函数被称为“加载时”,并且单击控件时什么也没有发生。在文本字段中键入内容并按Enter键时,仅调用addTask()。我想念什么?

2 个答案:

答案 0 :(得分:5)

使用:

onClick={deleteTask(this.props.cardId, t.id, index)}

该函数将在适当位置调用。尝试切换为:

onClick={() => deleteTask(this.props.cardId, t.id, index)}

为清楚起见,deleteTask是对函数的引用,deleteTask()调用函数。在需要调用该函数(例如,传递参数)的情况下,上面的模式是一个匿名函数,该函数调用您的deleteTask函数。

答案 1 :(得分:1)

在最后一个组件中创建一个函数,该函数使用适当的参数调用prop函数。也就是说,不要直接从onClick / onChange调用函数,以防那些道具期望引用函数,而不是调用函数的结果。

最重要的是,您应该签出Context API,以免遗漏太多道具。