Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/461.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 使用this.refs的弃用警告_Javascript_Reactjs - Fatal编程技术网

Javascript 使用this.refs的弃用警告

Javascript 使用this.refs的弃用警告,javascript,reactjs,Javascript,Reactjs,我有一个React组件,我想在单击时切换css类 所以我有这个: export class myComponent extends React.Component { constructor() { super(); this.state = { clicked: false }; this.handleClick = this.handleClick.bind(this); } render() { return ( <div&g

我有一个React组件,我想在单击时切换css类

所以我有这个:

export class myComponent extends React.Component {
  constructor() {
    super();
    this.state = { clicked: false };
    this.handleClick = this.handleClick.bind(this);
  }

  render() {
    return (
      <div>
        <div onClick={this.clicked}><span ref="btn" className="glyphicon">&nbsp;</span></div>
      </div>
    );
  }

  handleClick() {
    this.refs.btn.classList.toggle('active');
  }

  componentDidMount() {
    this.refs.btn.addEventListener('click', this.handleClick);
    this.setState({
      clicked: this.state.clicked = true,
    });
  }

  componentWillUnmount() {
    this.refs.btn.removeEventListener('click', this.handleClick);
    this.setState({
      clicked: this.state.clicked = false,
    });
  }
}
导出类myComponent扩展了React.Component{
构造函数(){
超级();
this.state={单击:false};
this.handleClick=this.handleClick.bind(this);
}
render(){
返回(
);
}
handleClick(){
this.refs.btn.classList.toggle('active');
}
componentDidMount(){
this.refs.btn.addEventListener('click',this.handleClick);
这是我的国家({
单击:this.state.clicked=true,
});
}
组件将卸载(){
this.refs.btn.removeEventListener('click',this.handleClick');
这是我的国家({
单击:this.state.clicked=false,
});
}
}
问题是ESLint一直告诉我“This.refs”被贬值了


我该怎么办?如何修复它,使其不使用折旧代码?

将调用您引用的Lint规则,并警告您:

"Using string literals in ref attributes is deprecated (react/no-string-refs)"
您收到此警告是因为您已经实现了使用
refs
(通过使用字符串)的不推荐方式。根据您的React版本,您可以执行以下操作:

反应16.3及更高版本
constructor(){
超级();
this.btnRef=React.createRef();
this.state={单击:false};
this.handleClick=this.handleClick.bind(this);
}
render(){
返回(
);
}

反应16.2及以上
constructor(){
超级();
this.btnRef;//不需要在这里声明变量,但我希望使它更可见。
this.state={单击:false};
this.handleClick=this.handleClick.bind(this);
}
render(){
返回(
this.btnRef=el}className=“glyphicon”>
);
}
为了获得更好的可读性,您还可以:

render() {
  let myRef = (el) => this.btnRef = el;
  return (
    <div>
      <div onClick={this.addVote}><span ref={myRef} className="glyphicon">&nbsp;</span></div>
    </div>
  );
}
render(){
让myRef=(el)=>this.btnRef=el;
返回(
);
}

查看官方文件中的内容,尤其是:

遗留API:字符串引用 如果您以前与React合作过,您可能会 熟悉较旧的API,其中
ref
属性是字符串,如
“textInput”
,DOM节点的访问方式为
this.refs.textInput
。我们 建议不要这样做,因为考虑了字符串引用 旧版和可能会在将来的某个版本中删除。如果 您当前正在使用
this.refs.textInput
访问refs,我们 建议使用回调模式


您可以尝试一种更具声明性的方式。我更改了您的代码以反映这一点。您只需提醒组件将在每次状态/道具更改时刷新并调用render。因此,我们可以在render方法中创建元素的类

import React from 'react'

export default class myComponent extends React.Component {
  constructor() {
    super();
    this.state = { clicked: false };
    this.handleClick = this.handleClick.bind(this);
  }

  render() {
    let btnClass = 'glyphicon'
    if(this.state.clicked){
      btnClass+=' active'
    }
    return (
      <div>
        <div onClick={this.handleClick}><span ref="btn" className={btnClass}>&nbsp;</span></div>
      </div>
    );
  }

  handleClick() {
    this.setState({
      clicked: !this.state.clicked
    })
  }
}
从“React”导入React
导出默认类myComponent扩展React.Component{
构造函数(){
超级();
this.state={单击:false};
this.handleClick=this.handleClick.bind(this);
}
render(){
让btnClass='glyphicon'
if(this.state.clicked){
btnClass+=“活动”
}
返回(
);
}
handleClick(){
这是我的国家({
单击:!this.state.clicked
})
}
}

此ESLint规则存在的原因是字符串引用即将退出。但是,对于上面的代码,我建议首先不要使用Ref

不要过度使用参考文献 React的优点是它是声明性的。也就是说,我们有一个状态和一个表达式(返回的JSX),表示给定特定状态时UI(更准确地说是DOM)的外观

只要使用状态和UI表达式就可以完成的事情都应该这样做。在上面的代码中使用Ref的问题是,它使代码成为必需的。我们无法理解仅仅从JSX来看DOM会是什么样子。以下是如何以声明方式实现相同的结果:

export class myComponent extends React.Component {
    constructor(props) {
        super(props);
        this.state = { 
            active: false 
        };
    }

    handleClick = () => {  // with arrow function there is no need for binding. 
        this.setState(
            prevState => {
                return {
                    active: !prevState.active
                }
            }
        )
    }

    render() {
        return (
            <div>
                <span 
                    onClick={this.handleClick} 
                    className={`glyphicon ${this.state.active && "active"}`}
                >
                    Hello World
                </span>
            </div>
        );
    }

}
导出类myComponent扩展了React.Component{
建造师(道具){
超级(道具);
this.state={
活动:错误
};
}
handleClick=()=>{//使用arrow函数,不需要绑定。
这是我的国家(
prevState=>{
返回{
活动:!prevState.active
}
}
)
}
render(){
返回(
你好,世界
);
}
}
当状态和UI表达式不足,并且需要访问实际DOM时,应该使用REF。例如,关注输入字段、滚动到元素或获取元素的确切宽度和高度

如果确实使用参照,请避免使用字符串参照 字符串引用会损害性能,不可组合,并且即将退出

字符串引用有一些问题,被认为是遗留的,并且很可能 将在将来的某个版本中删除。[正式文件]

[资源1][1],[资源2][1]

选项#1:使用React.createRef

class MyComponent extends Component {

    constructor(props) {
        super(props)
        this.myRef = React.createRef() // create a ref object 
    }

    render() {
        return <div ref={this.myRef}></div> // Attach the ref property to a dom element
    }

}
类MyComponent扩展组件{
建造师(道具){
超级(道具)
this.myRef=React.createRef()//创建一个ref对象
}
render(){
return//将ref属性附加到dom元素
}
}
选项#2:使用ref回调

class MyComponent extends Component {

    constructor(props){    // Optional, declare a class field
        super(props)
        this.myRef=null    
    }

    render() {
        return <div ref={ (ref) => this.myRef=ref }></div>
    }   // Attach the dom element to a class field

}
类MyComponent扩展组件{
构造函数(props){//可选,声明类字段
超级(道具)
this.myRef=null
}
render(){
返回此值。myRef=ref}>
}//将dom元素附加到类字段
}

顺便说一下,在设置状态中,您可以将它们指定为true或false,而无需使用this。。。我会使用onClick={setButtonState},然后在函数中,您只需设置状态并根据需要进行切换。我如何访问
componentWillUnmount()
life-cycle hook中的引用?@essaji,方法与您相同
class MyComponent extends Component {

    constructor(props) {
        super(props)
        this.myRef = React.createRef() // create a ref object 
    }

    render() {
        return <div ref={this.myRef}></div> // Attach the ref property to a dom element
    }

}
class MyComponent extends Component {

    constructor(props){    // Optional, declare a class field
        super(props)
        this.myRef=null    
    }

    render() {
        return <div ref={ (ref) => this.myRef=ref }></div>
    }   // Attach the dom element to a class field

}