React子组件上的调用方法 [英] Call methods on React children components

查看:41
本文介绍了React子组件上的调用方法的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想编写一个Form组件,该组件可以导出一种方法来验证其子级.不幸的是,表单没有看到"其子级上的任何方法.

I want to write a Form component that can export a method to validate its children. Unfortunately a Form does not "see" any methods on its children.

这是我定义Form的潜在子代的方式:

Here is how I define a potential children of Form:

var Input = React.createClass({
  validate: function() {
    ...
  },
});

这是我定义Form类的方式:

And here is how I define Form class:

var Form = React.createClass({
  isValid: function() {
    var valid = true;
    this.props.children.forEach(function(component) {
      // --> This iterates over all children that I pass
      if (typeof component.validate === 'function') {
        // --> code never reaches this point
        component.validate();
        valid = valid && component.isValid();
      }
    });
    return valid;
  }
});

我注意到我可以使用refs在子组件上调用方法,但不能通过props.children调用方法.

I noticed that I can call a method on a child component using refs, but I cannot call a method via props.children.

这种React行为是否有原因?

Is there a reason for this React behaviour?

我该如何解决?

推荐答案

技术原因是,当您尝试访问子组件时,它们实际上并不存在(在DOM中).它们尚未安装.它们已作为构造函数prop或方法作为react 传递给您的< Form> 组件.(因此在 React.createClass()中使用名称类).

The technical reason is that at the time you try to access the child component, they do not yet really exist (in the DOM). They have not been mounted yet. They have been passed to your<Form> component as a constructor prop or method as a react class. (hence the name class in React.createClass()).

正如您所指出的那样,可以使用refs来绕开它,但是我不建议这样做.在许多情况下,裁判往往是不想要的事情的捷径,因此应该避免.

As you point out, this can be circumvented by using refs, but I would not recommend it. In many cases, refs tend to be shortcuts for something that react wasn't intended for, and therefore should be avoided.

可能是设计使然,使父母很难/不可能使用孩子的方法.他们不应该这样做.如果孩子的方法对孩子是私密的,则应该在孩子的方法中:他们在孩子内部做某些事情,这些事情不应该直接向上传达给父母.如果真是这样,那么应该在父级内部进行处理.因为父母至少拥有孩子拥有的所有信息和数据.

It is probably by design that react makes it hard/ impossible for parents to access a child's methods. They are not supposed to. The child's methods should be in the child if they are private to the child: they do something inside the child that should not directly be communicated upward to the parent. If that were the case, than handling should have been done inside the parent. Because the parent has at least all info and data the child has.

现在您的情况是,我想象每个输入(子)组件都有某种特定的验证方法,该方法可以检查输入值,并根据结果进行一些错误消息反馈.假设在错误的字段周围有一个红色的轮廓.

Now in your case, I imagine each input (child) component to have some sort of specific validation method, that checks the input value, and based on outcome, does some error message feedback. Let's say a red outline around incorrect fields.

以反应方式,可以实现以下目的:

In the react way, this could be achieved as follows:

  • < Form> 组件具有状态,其中包括 runValidation 布尔值.
  • runValidation 设置为true后,在 setState({runValidation:true}); 中自动做出反应以重新渲染所有子项.
  • 如果您包含 runValidation 作为对所有子代的支持.
  • 然后每个孩子都可以使用类似 if(this.props.runValidation){this.validate()}
  • 的东西检查其 render()函数内部.
  • 将在子级中执行 validate()函数
  • validate函数甚至可以使用孩子的状态(当新道具进入时状态不会更改),并将其用于验证消息(例如,请在密码中添加更复杂的符号")
  • the <Form> component has state, which includes a runValidation boolean.
  • as soon as runValidation is set to true, inside a setState( { runValidation: true }); react automatically re-renders all children.
  • if you include runValidation as a prop to all children.
  • then each child can check inside their render() function with something like if (this.props.runValidation) { this.validate() }
  • which will execute the validate() function in the child
  • the validate function can even use the child's state (state is not changed when new props come in), and use that for the validation message (e.g. 'please add more complicated symbols to your password`)

现在,这还不能解决,就是您可能要在所有子级都验证自己之后,在表单级别进行一些检查:当所有孩子都还可以的时候,提交表格.

Now what this does not yet fix, is that you may want to do some checking at form level after all children have validated themselves: e.g. when all children are OK, submit the form.

要解决此问题,您可以将refs快捷方式应用于最终检查并提交.并在 componentDidUpdate()函数内的< Form> 中实现一个方法,以检查每个子代是否正常(例如具有绿色边框),以及是否单击了提交,然后提交.但一般而言,我强烈建议您不要使用引用.

To solve that, you could apply the refs shortcut to the final check and submit. And implement a method in your <Form> inside a componentDidUpdate() function, to check if each child is OK (e.g. has green border) AND if submit is clicked, and then submit. But as a general rule, I strongly recommend against using refs.

对于最终表格验证,一种更好的方法是:

For final form validation, a better approach is:

  • 在您的< Form> 内添加一个非状态变量,该变量保存每个孩子的布尔值.注意,它必须是非状态的,以防止孩子触发新的渲染周期.
  • 向每个孩子传递 validateForm 函数作为(回调)道具.
  • 在每个子对象的
  • 内部 validate()中,调用 this.props.validateForm(someChildID),这将更新Form中变量中的相应布尔值.
  • 在表单中 validateForm 函数的末尾,检查所有布尔值是否为真,如果是,则提交表单(或更改表单状态或其他).
  • add a non-state variable inside your <Form> which holds booleans for each child. NB, it has to be non-state, to prevent children from triggering a new render cycle.
  • pass a validateForm function as a (callback) prop to each child.
  • inside validate() in each child, call this.props.validateForm(someChildID) which updates the corresponding boolean in the variable in the Form.
  • at the end of the validateForm function in the Form, check if all booleans are true, and if so, submit the form (or change Form state or whatever).

对于在反应(使用助熔剂)中进行表单验证的更冗长(且方法更复杂)的解决方案,您可以检查

For an even more lengthy (and way more complicated) solution to form validation in react (with flux) you could check this article.

这篇关于React子组件上的调用方法的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆