最新公告
  • 欢迎您光临起源地模板网,本站秉承服务宗旨 履行“站长”责任,销售只是起点 服务永无止境!立即加入钻石VIP
  • 深入react技术--React与DOM, refs

    正文概述 掘金(千叶风行)   2021-02-17   488

    导言

    从 React 0.14版本后, React将 React中涉及DOM的操作剥离开,目的是为了抽象React,同时适用于web端和移动端。

    ReactDOM

    react-dom 包提供了DOM特定的方法,可以在你的应用程序的顶层使用,如果你需要的话,也可以作为React模型之外的特殊的操作DOM的接口。

    findDOMNode

    上一节我们已经讲过组件的生命周期, DOM真正被添加到 HTML中的生命周期方法是 componentDidMount 和 componentDidUpdate 方法。在这两个方法中,我们可以获取真正的 DOM元素。 React提供的获取DOM元素的方法有两种, 其中一种就是ReactDOM提供的 findDOMNode

    import React, { Component } from 'react';
    import ReactDOM from 'react-dom';
    
    class App extends Component {
    	componentDidMount() {
        	// this 为当前组件的实例
            const dom = ReactDOM.findDOMNode(this);
        }
        
        render() {}
    }
    

    如果在 render中返回 null,那么 findDOMNode 也返回null。 findDOMNode 只对已经挂载的组件有效。

    这个方法在严格模式React.StrictMode下会报错

    render

    ReactDOM.render(element, container[, callback])
    渲染一个 React 元素到由container 提供的DOM中, 并且返回组件的一个引用
    比如, react脚手架中经典的这段代码

    ReactDOM.render(
      <React.StrictMode>
        <App />
      </React.StrictMode>,
      document.getElementById('root')
    );
    

    unmountComponentAtNode()

    ReactDOM.unmountComponentAtNode(container)
    从 DOM 移除已装载的 React组件, 并清除器事件处理程序和 state 。
    如果在容器中没有挂载组件, 调用此函数什么也不做。 如果组件被卸载,则返回true. 如果没有要卸载的组件,则返回 false
    比如,可以这样

    ReactDOM.unmountComponentAtNode(document.getElementById('root'))
    

    react插槽

    插槽即 : ReactDOM.createPartal(child, container), 由 ReactDOM提供的接口。 可以实现将子节点渲染到父组件DOM层次结构之外的DOM节点。

    • child 可以是任何可渲染的 React子元素。例如,一个元素,字符串,片段(fragment)
    • container 则是一个DOM元素

    应用场景 对于 portal 的一个经典用例是当父组件有 overflow:hidden 或 z-index样式,但你需要子组件能够在视觉上 break out 其容器。 例如, 对话框, 提示框

    所以一般react组件里的模态框,就是这样实现的
    
    class Modal extends React.Component {
        constructor(props) {
            super(props);
    
            this.el = document.createElement('div');
        }
    
        componentDidMount() {
            appRoot.appendChild(this.el);
        }
    
        componentWillUnmount() {
            appRoot.removeChild(this.el);
        }
    
        render() {
            return ReactDOM.createPortal(
                this.props.children,
                this.el,
            );
        }
    }
    
    export default class App extends React.Component {
        constructor(props) {
            super(props);
            this.state = { showModal: false };
    
            this.handleShow = this.handleShow.bind(this);
            this.handleHide = this.handleHide.bind(this);
        }
    
        handleShow() {
            this.setState({ showModal: true });
        }
    
        handleHide() {
            this.setState({ showModal: false });
        }
    
        render() {
            const modal = this.state.showModal ? (
                <Modal>
                    <div>hello slot</div>
                </Modal>
            ) : null;
    
            return (
                <div className="app">
                    <button onClick={this.handleShow}>show modal</button>
                    {modal}
                </div>
            )
        }
    }
    

    refs

    refs是React组件中非常特殊的props,可以附加到任何一个组件上。 从字面意思上看, 组件被调用时会新建一个该组件的实例, 而refs就会指向这个实例。

    它可以是一个回调函数,这个回调函数会在组件被挂载后立即执行。

    ref的3种绑定方式

    string类型绑定

    类似于 vue中的ref绑定方式, 可以通过this.refs 绑定的 ref 的名字获取节点dom
    不过这种方法已经被遗弃了

    React.createRef()

    通过在class中使用React.createRef()方法创建一些变量,可以将这些变量绑定到标签的ref中
    那么该变量的current则指向绑定的标签dom

    export default class App extends Component {
        constructor(props) {
            super(props);
    
            this.handleClick = this.handleClick.bind(this);
    
            this.myRef = React.createRef();
        }
    
        handleClick() {
            this.myRef.current.focus();
        }
    
        render() {
            return (
                <div>
                    <input type="text" ref={this.myRef}/>
                    <input type="button" value="Foucs the text input" onClick={this.handleClick}/>
                </div>
            )
        }
    }
    
    函数形式

    在class中声明函数,在函数中绑定ref
    使用这种方法可以将子组件暴露给父组件以使得父组件能够调用子组件的方法

    class Child extends React.Component {
        constructor(props) {
            super (props);
    
            this.state = {
                count: 1,
            }
        }
    
        Myclick = () => {
            this.setState({
                count: this.state.count + 1
            })
        }
    
        render() {
            return (
                <div>{this.state.count}</div>
            )
        }
    }
    
    export default class App extends React.Component {
        handleClick = () => {
            this.childRef.Myclick()
        }
    
        render() {
            return (
                <div>
                    <Child ref={ref => this.childRef = ref}/>
                    <button onClick={this.handleClick}>add</button>
                </div>
            )
        }
    }
    

    起源地下载网 » 深入react技术--React与DOM, refs

    常见问题FAQ

    免费下载或者VIP会员专享资源能否直接商用?
    本站所有资源版权均属于原作者所有,这里所提供资源均只能用于参考学习用,请勿直接商用。若由于商用引起版权纠纷,一切责任均由使用者承担。更多说明请参考 VIP介绍。
    提示下载完但解压或打开不了?
    最常见的情况是下载不完整: 可对比下载完压缩包的与网盘上的容量,若小于网盘提示的容量则是这个原因。这是浏览器下载的bug,建议用百度网盘软件或迅雷下载。若排除这种情况,可在对应资源底部留言,或 联络我们.。
    找不到素材资源介绍文章里的示例图片?
    对于PPT,KEY,Mockups,APP,网页模版等类型的素材,文章内用于介绍的图片通常并不包含在对应可供下载素材包内。这些相关商业图片需另外购买,且本站不负责(也没有办法)找到出处。 同样地一些字体文件也是这种情况,但部分素材会在素材包内有一份字体下载链接清单。
    模板不会安装或需要功能定制以及二次开发?
    请QQ联系我们

    发表评论

    还没有评论,快来抢沙发吧!

    如需帝国cms功能定制以及二次开发请联系我们

    联系作者

    请选择支付方式

    ×
    迅虎支付宝
    迅虎微信
    支付宝当面付
    余额支付
    ×
    微信扫码支付 0 元