热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

反应调用子方法的不同方式-Reactdifferentwaysofcallingachildmethod

ReactsaysweshouldnotuserefswherepossibleandInoticedthatyoucantuseshallowrendering

React says we should not use refs where possible and I noticed that you can't use shallow rendering testing with refs so I have tried to remove refs where possible. I have a child component like this:

React说我们不应该在可能的地方使用refs,我注意到你不能使用refs进行浅层渲染测试,所以我试图在可能的情况下删除refs。我有一个像这样的子组件:

class Child extends React.Component {
    play = () => {
        //play the media
    },
    pause = () => {
        //pause the media
    },
    setMedia = (newMedia) => {
        //set the new media
    }
}

I then have a parent component that needs to call these methods. For the setMedia I can just use props with the componentWillReceiveProps and call setMedia when the new props come in to the child.

然后我有一个需要调用这些方法的父组件。对于setMedia,我可以使用带有componentWillReceiveProps的props,并在新的props进入子进程时调用setMedia。

With the play and pause functions I cannot do this.

有了播放和暂停功能,我无法做到这一点。

Ben Alpert replied to this post and said:

Ben Alpert回复了这篇文章说:

In general, data should be passed down the tree via props. There are a few exceptions to this (such as calling .focus() or triggering a one-time animation that doesn't really "change" the state) but any time you're exposing a method called "set", props are usually a better choice. Try to make it so that the inner input component worries about its size and appearance so that none of its ancestors do.

通常,数据应该通过props传递到树下。这有一些例外(例如调用.focus()或触发一次性动画并不真正“改变”状态)但是当你暴露一个名为“set”的方法时,通常会出现道具一个更好的选择。尝试做到这一点,以便内部输入组件担心它的大小和外观,以便它的祖先没有。

Which is the best way to call a child function?

哪个是调用子函数的最佳方法?

  1. play() and pause() methods can be called from refs as they do not change the state just like focus() and use props for the other functions that have arguments.
  2. play()和pause()方法可以从refs中调用,因为它们不像focus()那样改变状态,并且对具有参数的其他函数使用props。

  3. Call the child functions by passing the method name in although this just seems hacky and a lot more complex:

    通过传递方法名称来调用子函数,尽管这看起来很简单,而且更复杂:

    class Child extends React.Component {
        play = () => {
            //play the media
        },
        pause = () => {
            //pause the media
        },
        setMedia = (newMedia) => {
            //set the new media
        },
        _callFunctiOns= (functions) => {
            if (!functions.length) {
                return;
            }
    
            //call each new function
            functions.forEach((func) => this[func]());
    
            //Empty the functions as they have been called
            this.props.updateFunctions({functions: []});
        } 
        componentWillReceiveProps(nextProps) {
            this._callFunctions(nextProps.functions);
        }
    }
    
    class Parent extends React.Component {
        updateFunctiOns= (newFunctions) => this.setState({functions: newFunctions});
        differentPlayMethod = () => {
            //...Do other stuff
            this.updateFunctions("play");
        }
        render() {
            return (
                
            );
        }
    }
    
  4. Do this in the child component: this.props.updateFunctions({play: this.play}); The problem with this is that we are exposing(copying) a method to another component that shouldn't really know about it...

    在子组件中执行此操作:this.props.updateFunctions({play:this.play});这个问题是我们将一个方法暴露(复制)到另一个不应该真正了解它的组件......

Which is the best way to do this?

这是最好的方法吗?

I am using method number 2 at the moment and I don't really like it.

我现在正在使用方法2,我真的不喜欢它。

To override child functions I have also done something similar to above. Should I just use refs instead?

为了覆盖子函数,我也做了类似于上面的事情。我应该只使用refs吗?

2 个解决方案

#1


2  

Rather than call child functions, try to pass data and functions down from the parent. Alongside your component, you can export a wrapper or higher order function that provides the necessary state / functions.

而不是调用子函数,尝试从父级传递数据和函数。除了组件,您还可以导出提供必要状态/功能的包装器或更高阶函数。

let withMedia = Wrapped => {
  return class extends React.Component {
    state = { playing: false }
    play() { ... }
    render() {
      return (
        
      )
    }
  }
}

Then in your parent component:

然后在您的父组件中:

import { Media, withMedia } from 'your-library'

let Parent = props =>
  
export default withMedia(Parent)

#2


0  

Keep the state as localized as you can, but don't spread it over multiple components. If you need the information whether it is currently playing in both the parent and the child, keep the state in the parent.

保持状态尽可能本地化,但不要将其分布在多个组件上。如果您需要有关父级和子级当前是否正在播放的信息,请将状态保留在父级中。

This leaves you with a much cleaner state tree and props:

这将为您提供更清晰的状态树和道具:

class Child extends React.Component {
  render() {
    return (
      

Playing: {this.props.playing ? 'Yes' : 'No'}

); } } class Parent extends React.Component { constructor(props) { super(props); this.togglePlay = this.togglePlay.bind(this); this.state = { playing: false }; } togglePlay() { this.setState({ playing: !this.state.playing }); } render() { return (
); } } ReactDOM.render( , document.getElementById('app') );




推荐阅读
  • 本文介绍了闭包的定义和运转机制,重点解释了闭包如何能够接触外部函数的作用域中的变量。通过词法作用域的查找规则,闭包可以访问外部函数的作用域。同时还提到了闭包的作用和影响。 ... [详细]
  • 目录实现效果:实现环境实现方法一:基本思路主要代码JavaScript代码总结方法二主要代码总结方法三基本思路主要代码JavaScriptHTML总结实 ... [详细]
  • 原文地址:https:www.cnblogs.combaoyipSpringBoot_YML.html1.在springboot中,有两种配置文件,一种 ... [详细]
  • javascript  – 概述在Firefox上无法正常工作
    我试图提出一些自定义大纲,以达到一些Web可访问性建议.但我不能用Firefox制作.这就是它在Chrome上的外观:而那个图标实际上是一个锚点.在Firefox上,它只概述了整个 ... [详细]
  • Voicewo在线语音识别转换jQuery插件的特点和示例
    本文介绍了一款名为Voicewo的在线语音识别转换jQuery插件,该插件具有快速、架构、风格、扩展和兼容等特点,适合在互联网应用中使用。同时还提供了一个快速示例供开发人员参考。 ... [详细]
  • 闭包一直是Java社区中争论不断的话题,很多语言都支持闭包这个语言特性,闭包定义了一个依赖于外部环境的自由变量的函数,这个函数能够访问外部环境的变量。本文以JavaScript的一个闭包为例,介绍了闭包的定义和特性。 ... [详细]
  • 本文介绍了在wepy中运用小顺序页面受权的计划,包含了用户点击作废后的从新受权计划。 ... [详细]
  • 本文介绍了如何使用elementui分页组件进行分页功能的改写,只需一行代码即可调用。通过封装分页组件,避免在每个页面都写跳转请求的重复代码。详细的代码示例和使用方法在正文中给出。 ... [详细]
  • 本文介绍了网页播放视频的三种实现方式,分别是使用html5的video标签、使用flash来播放以及使用object标签。其中,推荐使用html5的video标签来简单播放视频,但有些老的浏览器不支持html5。另外,还可以使用flash来播放视频,需要使用object标签。 ... [详细]
  • Java实战之电影在线观看系统的实现
    本文介绍了Java实战之电影在线观看系统的实现过程。首先对项目进行了简述,然后展示了系统的效果图。接着介绍了系统的核心代码,包括后台用户管理控制器、电影管理控制器和前台电影控制器。最后对项目的环境配置和使用的技术进行了说明,包括JSP、Spring、SpringMVC、MyBatis、html、css、JavaScript、JQuery、Ajax、layui和maven等。 ... [详细]
  • 如何使用Java获取服务器硬件信息和磁盘负载率
    本文介绍了使用Java编程语言获取服务器硬件信息和磁盘负载率的方法。首先在远程服务器上搭建一个支持服务端语言的HTTP服务,并获取服务器的磁盘信息,并将结果输出。然后在本地使用JS编写一个AJAX脚本,远程请求服务端的程序,得到结果并展示给用户。其中还介绍了如何提取硬盘序列号的方法。 ... [详细]
  • 本文讨论了如何在codeigniter中识别来自angularjs的请求,并提供了两种方法的代码示例。作者尝试了$this->input->is_ajax_request()和自定义函数is_ajax(),但都没有成功。最后,作者展示了一个ajax请求的示例代码。 ... [详细]
  • 本文记录了在vue cli 3.x中移除console的一些采坑经验,通过使用uglifyjs-webpack-plugin插件,在vue.config.js中进行相关配置,包括设置minimizer、UglifyJsPlugin和compress等参数,最终成功移除了console。同时,还包括了一些可能出现的报错情况和解决方法。 ... [详细]
  • 本文介绍了如何使用vue-awesome-swiper组件,包括在main.js中引入和使用swiper和swiperSlide组件,以及设置options和ref属性。同时还介绍了如何在模板中使用swiper和swiperSlide组件,并展示了如何通过循环渲染swipes数组中的数据,并使用picUrl属性显示图片。最后还介绍了如何添加分页器。 ... [详细]
  • 如何用JNI技术调用Java接口以及提高Java性能的详解
    本文介绍了如何使用JNI技术调用Java接口,并详细解析了如何通过JNI技术提高Java的性能。同时还讨论了JNI调用Java的private方法、Java开发中使用JNI技术的情况以及使用Java的JNI技术调用C++时的运行效率问题。文章还介绍了JNIEnv类型的使用方法,包括创建Java对象、调用Java对象的方法、获取Java对象的属性等操作。 ... [详细]
author-avatar
专注自由近_515
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有