React-如何将道具传递给孙子组件?

时间:2018-09-28 12:10:56

标签: javascript reactjs

我知道这里有类似的线程,但是它们中的任何一个仍然无法帮助我。 我试图将deleteItem()组件中的parent函数传递给grandson组件中的onClick参数。 请查看组件,然后告诉我什么地方出了问题,在孙子组件中访问该功能应该怎么做?

Parent - https://codeshare.io/2E39oO
Child - https://codeshare.io/5XnwN8
Grandson - https://codeshare.io/5z9JXE

1 个答案:

答案 0 :(得分:0)

这是我发现的两件事

  • 在deleteHandler中拼写错误(已经提到)
  • 该按钮已被禁用,因此不会触发事件

我最终遇到的例子

class ToDo extends Component {
  constructor(props) {
    super(props);
    this.state = {
      list: [
        {
          title: "Cup cleaning",
          todo: "Wash and take away the Kurzhiy's cup from WC"
        },
        {
          title: "Smoking rollton",
          todo: "Do some rollton and cigarettes"
        },
        {
          title: "Curious dream",
          todo: "Build a time machine"
        }
      ],
      title: "",
      todo: ""
    };
  }

  createNewToDoItem = () => {
    this.setState(({ list, title, todo }) => ({
      list: [
        ...list,
        {
          title,
          todo
        }
      ],
      title: "",
      todo: ""
    }));
  };

  handleKeyPress = e => {
    if (e.target.value !== "") {
      if (e.key === "Enter") {
        this.createNewToDoItem();
      }
    }
  };

  handleTitleInput = e => {
    this.setState({
      title: e.target.value
    });
  };

  handleTodoInput = e => {
    this.setState({
      todo: e.target.value
    });
  };

  deleteItem(indexToDelete) {
    console.log("HERE");
    this.setState(({ list }) => ({
      list: list.filter((toDo, index) => index !== indexToDelete)
    }));
  }

  editItem = (i, updTitle, updToDo) => {
    let arr = this.state.list;
    arr[i].title = updTitle;
    arr[i].todo = updToDo;
    this.setState({ list: arr });
  };

  eachToDo = (item, i) => {
    return (
      <ToDoItem
        key={i}
        title={item.title}
        todo={item.todo}
        deleteItem={this.deleteItem.bind(this, i)}
        editItem={this.editItem.bind(this, i)}
      />
    );
  };

  render() {
    return (
      <div className="ToDo">
        <h1 className="ToDo-Header" />
        <div className="ToDo-Container">
          <div className="ToDo-Content">
            {this.state.list.map(this.eachToDo)}
          </div>

          <div>
            <input
              type="text"
              placeholder="Enter new title"
              value={this.state.title}
              onChange={this.handleTitleInput}
              onKeyPress={this.handleKeyPress}
            />
            <input
              type="text"
              placeholder="Enter new todo"
              value={this.state.todo}
              onChange={this.handleTodoInput}
              onKeyPress={this.handleKeyPress}
            />
            {/* <AddButton addHandler={this.createNewToDoItem} /> */}
          </div>
        </div>
      </div>
    );
  }
}

class ToDoItem extends Component {
  constructor(props) {
    super(props);
    this.state = {
      editMode: false
    };
  }

  edit = () => {
    this.setState({ editMode: true });
  };

  save = () => {
    let updTitle = this.refs.newTitle.value;
    let updToDo = this.refs.newToDo.value;
    this.props.editItem(updTitle, updToDo);

    this.setState({
      editMode: false
    });
  };

  renderNormal = () => {
    return (
      <div className="ToDoItem">
        <p className="ToDoItem-Text">{this.props.title}</p>
        <p className="ToDoItem-Text">{this.props.todo}</p>
        {/* <EditButton editHandler={this.edit} /> */}
        <FloatingActionButtons deleteHandler={this.props.deleteItem} />
        {/* <button className="ToDoItem-Button" id="editbtn" onClick={this.edit}>&#x270D;</button> */}
        {/* <button className="ToDoItem-Button" id="delbtn" onClick={this.props.deleteItem}>&minus;</button> */}
      </div>
    );
  };

  renderEdit = () => {
    return (
      <div className="ToDoItem">
        <textarea ref="newTitle" defaultValue={this.props.title} />
        <textarea ref="newToDo" defaultValue={this.props.todo} />
        <button onClick={this.save} className="ToDoItem-Button" id="savebtn">
          &#128190;
        </button>
      </div>
    );
  };

  render() {
    if (this.state.editMode) {
      return this.renderEdit();
    } else {
      return this.renderNormal();
    }
  }
}

const styles = theme => ({
  button: {
    margin: theme.spacing.unit
  }
});

function FloatingActionButtons(props) {
  return (
    <div>
      <Button variant="fab" aria-label="Delete" onClick={props.deleteHandler}>
        Delete
      </Button>
    </div>
  );
}

FloatingActionButtons.propTypes = {
  classes: PropTypes.object.isRequired
};