天行健, 君子以自强不息
Sunny's Blog
Title

React Refs and the DOM

Refs provide a way to access DOM nodes or React elements created in the render method. 正常React数据流中,父组件通过props与其子组件进行交互,子组件的re-render需要改变父组件向其传的props值。ref主要有两个功能,一个是获取DOM nodes(主要用于非控的form组件),一个是在父组件中获取子组件的方法(你可以理解成是父组件中的action触发了其某一个子组件的UI变化,而你不希望其他子组件也变化,其实这个时候如果需求频繁,更好的方法是用flux)

refs不建议滥用的原因是它不符合传统的react数据流动规则,比如state触发

ref有两创建方法:Creating Refs和Callback Refs. 而根据ref是放置在DOM上还是Class component上,决定了ref的取值

下面是学习时的测试源码

                    import React from 'react';
                    import ReactDOM from 'react-dom';

                    class Test2 extends React.Component {
                        constructor(props) {
                            super(props);
                            this.textInput2 = React.createRef();
                            this.focusTextInput2 = this.focusTextInput2.bind(this);
                        }
                        focusTextInput2(){
                            //Note: we're accessing "current" to get the DOM node
                            this.textInput2.current.focus();
                        }
                        render() {
                            return (
                                <input type="text" ref={this.textInput2} />
                            );
                        }
                    }

                    class RefsTest extends React.Component {
                        constructor(props) {
                            super(props);
                            this.textInput1 = React.createRef();
                            this.focusTextInput1 = this.focusTextInput1.bind(this);
                            this.textInput2 = React.createRef();
                        }
                        focusTextInput1(){
                            //Note: we're accessing "current" to get the DOM node
                            //获取DOM nodes
                            this.textInput1.current.focus();
                        }

                        componentDidMount() {
                            //在父组件中获取子组件的方法
                            this.textInput2.current.focusTextInput2();
                        }

                        render(){
                            return(
                                <div>
                                    <div>
                                        {
                                            //1)Creating Refs and Adding a Ref to a DOM Element
                                        }
                                        <input type="text" ref={this.textInput1} />
                                        <button onClick={this.focusTextInput1}>Focus the text input1</button>
                                        {
                                            //2)Creating Refs and Adding a Ref to a Class Component
                                        }
                                        <Test2 ref={this.textInput2} />
                                        {
                                            //Refs and Functional Components. You may not use the ref attribute on functional components because they don’t have instances
                                            //But, You can use the ref attribute inside a functional component
                                        }
                                    </div>
                                    {                    
                                        //还有一种callback refs的方法是直接ref = { element => this.textInput = element }
                                        //在this.textInput.focus();的时候注意不需要用到current了

                                        class CustomTextInput extends React.Component {
                                          constructor(props) {
                                            super(props);

                                            this.textInput = null;

                                            this.setTextInputRef = element => {
                                              this.textInput = element;
                                            };

                                            this.focusTextInput = () => {
                                              // Focus the text input using the raw DOM API
                                              if (this.textInput) this.textInput.focus();
                                            };
                                          }

                                          componentDidMount() {
                                            // autofocus the input on mount
                                            this.focusTextInput();
                                          }

                                          render() {
                                            // Use the `ref` callback to store a reference to the text input DOM
                                            // element in an instance field (for example, this.textInput).
                                            return (
                                              <div>
                                                <input
                                                  type="text"
                                                  ref={this.setTextInputRef}
                                                />
                                                <input
                                                  type="button"
                                                  value="Focus the text input"
                                                  onClick={this.focusTextInput}
                                                />
                                              </div>
                                            );
                                          }
                                        }
                                    }
                                </div>
                            )
                        }
                    }

                    export { RefsTest as default };
            
            
地势坤,君子以厚德载物