反应将onClick作为道具传递给所需的子组件吗?

时间:2019-05-20 16:19:34

标签: javascript reactjs

我试图通过将onClick添加到父组件来触发子组件内部的onClick函数调用。它不起作用。

// parent component
class MainForm extends Component {
  // code here

  handleClick = () => {
    console.log('clicked!');
  }

  render {
    return (
    <Linkbutton
        text="Click Me!"
        onClick={this.handleClick}>
    />
  );
};

// sub component
export const LinkButton = (props) => {
  return (
    <button>{props.text}</button>
  );
};

这不起作用。点击时未调用onClick函数。我也设法通过在子组件中添加onClick调用来解决此问题。

// sub component
export const LinkButton = (props) => {
  return (
    <button onClick={props.onClick}>{props.text}</button>
  );
};

这有效。我的问题是为什么? onClick不应在任何元素上调用,无论其内部是什么?为什么还要将其显式传递给子组件?

我想了解这种方式的原因以及为什么它不能以我尝试的第一种方式起作用。谢谢!

4 个答案:

答案 0 :(得分:0)

原因是您创建的LinkBut​​ton组件只是一个javascript对象,而不是DOM节点,因此它没有像onClick这样的事件处理程序。 button元素被转换为实际的DOM元素,因此它将具有与实际的HTML元素相关的所有关联事件处理程序。

将onClick道具添加到LinkBut​​ton组件时,它只是对象的属性。通过从该组件内部调用props.onClick,您只是在调用一个存储在属性内部的函数,类似于:

let props = {
    onClick: function () { alert("Executed!"); }
};

props.onClick();

希望这对您有帮助!

答案 1 :(得分:0)

在第一个示例中,您实际上并没有添加onClick事件。仅将引用传递给组件并不意味着它会自动知道如何处理它。

第二个示例实际上确实像应该的那样将onClick添加到了按钮,这就是它起作用的原因。

在第一个示例中,您将“ onClick”用作参数,而不是实际的事件处理程序。

答案 2 :(得分:0)

您有点困惑。您在onClick组件中传递的Linkbutton道具不会触发函数调用。在反应中,我们使用道具来在组件之间进行通信。 onClickbutton元素中的事件,而onClickLinkbutton组件中的道具。

答案 3 :(得分:0)

不幸的是,在纯React.js中无法解决这个问题。如果希望父元素的函数处理在子元素上执行的click事件,则必须将该函数作为道具明确传递给子元素。

我理解为什么有时可能会感到沮丧,尤其是当您有一个高大的组件树并且该树的许多叶子必须调用父对象,父对象的父对象甚至父对象的父对象的方法时父[...]元素。

减轻该问题的一种方法(尤其是在您的项目变大时)是使用实现Flux模式的状态存储。 Redux是一个很好的例子。而不是调用从父组件传递来的方法作为道具(这种方法在大多数情况下会改变父组件的状态),您的按钮组件将调度一个动作,然后由化简函数处理,从而更新应用程序的全局状态。然后,依赖于已更改的全局状态部分的应用程序的所有组件都将相应更新。在此示例中,按钮组件将不会直接与父元素通信。它只会调度一个动作。

Here is a great tutorial,如果您决定学习Redux,则应该阅读。切记,Redux通常被认为很难入门,因此它最适合大型应用程序,因为避免将由Redux引起的所有问题的能力大大抵消了因将Redux添加到应用程序而引起的项目复杂性的最初增加组件之间的直接通信。