带参数的回调函数ReactJS

时间:2017-07-27 19:07:50

标签: javascript reactjs

使用ReactJS并且无法理解callback functions如何使用ReactJS。

我有一个标题为TodoFormComponent的父组件,它初始化了我的待办事项列表。我在TodoItemsComonent上创建了一个回调函数,但它不会触发updateItem方法并显示selected项。

  

问题:如何将数据从孩子传递给父母?我想将选定的待办事项传递给父项,以便我可以更新主待办事项列表。

父组件(TodoFormComponent)

TodoFormComponentselectedTask,应触发updateItem方法。

import * as React from "react";
import TodoItemsComponent from "../todo-items/todo-items.component";
import AddTodoItemComponent from "../add-todo-item/add-todo-item.component";

export default class TodoFormComponent extends React.Component {
    constructor(){
        super();
        this.state = {
            todoItems: [
                { id: '1', todo: 'First Todo Item' },
                { id: '2', todo: 'Second Todo Item' },
                { id: '3', todo: 'Third Todo Item' }
            ],
            selected: {}
        };

        this.updateItem = this.updateItem.bind(this);
    }

    updateItem () {
        console.log('Selected Value:: ', this.state.selected);
    }

    render() {
        return (
            <div className="row">
                <div className="container">
                    <div className="well col-xs-6 col-xs-offset-3">
                        <h1>To do: </h1>
                        <div name="todo-items">
                            <TodoItemsComponent items={this.state.todoItems} selectedTask={() => {this.updateItem}}/>
                        </div>
                        <div name="add-todo-item">
                            <AddTodoItemComponent/>
                        </div>
                    </div>
                </div>
            </div>
        )
    }
}

子组件(TodoItemsComponent)

TodoItemsComponentonClick来更新所选值。这会在selectedTask函数中更新。     import * as React from“react”;

export default class TodoItemsComponent extends React.Component {
    constructor(props) {
        super(props);
    }

    selectedTask (item) {
        this.setState({selected: item})
    }

    render() {
        return (
            <ul className="list-group">
                {
                    this.props.items.map((item) => {
                        return (
                            <li className="list-group-item">
                                {item.todo}
                                <div className="pull-right">
                                    <button
                                        type="button"
                                        className="btn btn-xs btn-success">
                                        &#x2713;
                                    </button> <button
                                        type="button"
                                        className="btn btn-xs btn-danger"
                                        onClick={() => {this.selectedTask(item)}}
                                        >&#xff38;
                                    </button>
                                </div>
                            </li>
                        )
                    })
                }
            </ul>
        )
    }
}

5 个答案:

答案 0 :(得分:10)

每当您想要将数据从子节点传递给父节点时,您将一个函数作为prop传递给子节点,并从子节点传递,使用this.props.passedFunction(yourDataToPassToParent)

调用该函数

在您的父组件中,您将selectedTask函数作为prop传递,因此您应该使用要传递给父级的数据调用this.prop.selectedTask(),如下所示:

<button
  type="button"
  className="btn btn-xs btn-danger"
  onClick={() => {this.props.selectedTask(item)}}
 >
  &#xff38;
 </button>

您在父母中传递selectedTask的方式也是错误的。你应该这样传递它:

<TodoItemsComponent items={this.state.todoItems} selectedTask={this.updateItem}/>

答案 1 :(得分:1)

在您的TodoItemsComponent中,updateItem()作为prop传递。因此,您需要在onClick方法中调用this.props.updateItem()

所以你的按钮应该是:

                 <button
                 type="button"
                 className="btn btn-xs btn-danger"
                 onClick={() => 
                     {this.props.selectedTask(item)}}>&#xff38;
                 </button>

并更新您的父组件UpdateItem方法以接收属性作为项目。像这样:

updateItem (e) {
    console.log('Selected Value:: ', e);
}

要通过孩子的方法,你需要

             <TodoItemsComponent items=
                 {this.state.todoItems} selectedTask={this.updateItem}/>

如果你这样做:{()=>this.updateItem()}那么它将初始化方法。所以你只需要传递函数参考。

答案 2 :(得分:0)

您必须将updateItem作为prop发送给子Component。

const Parent = () => 
<div>
  <TodoItemsComponent items={this.state.todoItems} selectedTask={updateItem}/>
</div>

同时更新

updateItem (item) {  
   this.setState({ selected: item })
   console.log( 'Selected Value:: ', item);
}

答案 3 :(得分:0)

一些伪代码:

class Parent extends React.Component {
    render() {
        return (<Child id={1} onClick={(id) => console.log(id)}/>);
    }
}

class Child extends React.Component {
    render() {
        return (<div onClick={() => this.props.onClick(this.props.id)}></div>);
    }
}

Console.log将输出“1”

更多:link

答案 4 :(得分:0)

固定代码:

class TodoItemsComponent extends React.Component {
  constructor(props) {
    super(props);
  }

  render() {
    return (
      <ul className="list-group">
        {this.props.items.map(item => {
          return (
            <li className="list-group-item">
              {item.todo}
              <div className="pull-right">
                <button type="button" className="btn btn-xs btn-success">
                  &#x2713;
                </button>{" "}
                <button
                  type="button"
                  className="btn btn-xs btn-danger"
                  onClick={() => {
                    this.props.selectedTask(item);
                  }}
                >
                  &#xff38;
                </button>
              </div>
            </li>
          );
        })}
      </ul>
    );
  }
}

class TodoFormComponent extends React.Component {
  constructor() {
    super();
    this.state = {
      todoItems: [
        { id: "1", todo: "First Todo Item" },
        { id: "2", todo: "Second Todo Item" },
        { id: "3", todo: "Third Todo Item" }
      ],
      selected: {}
    };

    this.updateItem = this.updateItem.bind(this);
  }

  updateItem(item) {
    this.setState({ selected: item });
  }

  render() {
    return (
      <div className="row">
        <div className="container">
          <div className="well col-xs-6 col-xs-offset-3">
            <h1>To do: </h1>
            <h3>
              Selected task: {JSON.stringify(this.state.selected)}
            </h3>
            <div name="todo-items">
              <TodoItemsComponent
                items={this.state.todoItems}
                selectedTask={this.updateItem}
              />
            </div>
            <div name="add-todo-item" />
          </div>
        </div>
      </div>
    );
  }
}

const App = () => <TodoFormComponent />;

ReactDOM.render(<App />, document.getElementById("root"));
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.min.js"></script>
<div id="root"></div>

playground:https://codesandbox.io/s/LgrGKK9og