【问题标题】:Callback Function With Parameters ReactJS带参数的回调函数 ReactJS
【发布时间】:2018-01-03 16:11:24
【问题描述】:

使用 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)


TodoItemsComponent 有一个onClick 来更新选定的值。这在 selectedTask 函数中得到更新。 从 "react" 导入 * as 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>
        )
    }
}

【问题讨论】:

    标签: javascript reactjs


    【解决方案1】:

    每当您想将数据从子级传递给父级时,您将一个函数作为道具传递给子级,然后从子级调用该函数,使用this.props.passedFunction(yourDataToPassToParent)

    在您的父组件中,您将 selectedTask 函数作为道具传递,因此您应该调用 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}/>
    

    【讨论】:

    • 哦,是的,你就是那个男人! :) 这成功了……我试图在父级上执行 lambda 函数,这阻止了它触发我的方法。谢谢!
    【解决方案2】:

    在您的 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}/>
    

    如果你这样做:{()=&gt;this.updateItem()} 那么它将初始化该方法。所以你只需要传递函数引用。

    【讨论】:

    • 我更新了子组件,但这仍然没有触发我的父组件方法updateItem。还有其他想法吗?
    • 在你的父组件中改变这个
    【解决方案3】:

    固定代码:

    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>

    游乐场:https://codesandbox.io/s/LgrGKK9og

    【讨论】:

      【解决方案4】:

      一些伪代码:

      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

      【讨论】:

        【解决方案5】:

        您必须将 updateItem 作为道具发送给子组件。

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

        也更新了

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

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2015-04-29
          • 1970-01-01
          • 2012-10-11
          • 1970-01-01
          • 2017-12-25
          • 2015-08-29
          相关资源
          最近更新 更多