我正在开发具有以下组件层次结构的应用程序(由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()。我想念什么?
答案 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,以免遗漏太多道具。