我该如何在React中触发几个更高组件的功能?

时间:2019-05-31 22:31:10

标签: reactjs react-component

只需学习React,我想在真棒字体图标上添加onClick,然后运行markTaskAsCompleted函数。我有麻烦,因为它是层次结构中较低的几个组件。您理想情况下将如何进行?请记住,我还必须在函数中传递任务的ID。

class TasksBase extends React.Component {

  constructor(props) {
    super(props);
    this.state = {
      loading: false,
      tasks: [],
    };
  }

  componentDidMount() {
    this.onListenForTasks();
  }

  onListenForTasks() {
    this.setState({ loading: true });
    this.unsubscribe = this.props.firebase
      .tasks()
      .orderBy('created', 'desc')
      .onSnapshot(snapshot => {
        if (snapshot.size) {
          let tasks = [];
          snapshot.forEach(doc =>
            tasks.push({ ...doc.data(), uid: doc.id }),
          );
          this.setState({
            tasks: tasks,
            loading: false
          });
        } else {
          this.setState({ tasks: null, loading: false });
        }
    });
  }

  markTaskAsCompleted(){
    console.log("Completed");
  }

  componentWillUnmount() {
    this.unsubscribe();
  }

  render() {
    const { tasks, loading } = this.state;
    return (
      <div>
        {loading && <div>Loading ...</div>}
        {tasks ? (
          <TaskList tasks={tasks} />
        ):(
          <div>There are no tasks ...</div>
        )}
      </div>
    );
  }

}


const Tasks = withFirebase(TasksBase);

const TaskList = ({ tasks }) => (
  <ul className="tasks">
    {tasks.map( task => (
      <Task key={task.uid} task={task} />
    ))}
  </ul>
);

const Task = ({ task }) => (
  (!task.completed && !task.obsolete && !task.waitingForDependencies) &&
  <li className="task">
    <strong>{task.userId}</strong> {task.name}
    <div className="icons">
      <FontAwesomeIcon icon="check-circle"/>
      <FontAwesomeIcon icon="times-circle" />
    </div>
  </li>
);

const condition = authUser => !!authUser;

export default compose(
  withEmailVerification,
  withAuthorization(condition),
)(Tasks);

2 个答案:

答案 0 :(得分:1)

在构造函数中绑定您的类函数:

this.markTaskAsCompleted = this.markTaskAsCompleted.bind(this);

使用prop将函数传递到子组件中:

<TaskList tasks={tasks} handleMarkCompleted={this.markTaskAsCompleted} />

再次将函数传递给子组件,这是道具钻,不是最新的最佳方法,但是可以起作用:

const TaskList = ({ tasks, handleMarkCompleted }) => (
  <ul className="tasks">
    {tasks.map( task => (
      <Task key={task.uid} task={task} handleMarkCompleted={handleMarkCompleted} />
    ))}
  </ul>
);

使用onClick触发函数:

inside <Task>...
<FontAwesomeIcon icon="check-circle" onClick={() => handleMarkCompleted(task.uid)} />

如果将数据传递到函数(例如task.uid)中,也要使其成为函数定义中的参数,则可以使用它:

markTaskAsCompleted(id){
    console.log("Completed", id);
}

答案 1 :(得分:0)

您将需要像

一样将其传递到树上
  

markTaskAsCompleted = {this.props.markTaskAsCompleted}

并确保该函数绑定到构造函数中的父级。

u可以使用refs或document.getElementById来获取ID。