【问题标题】:React component can't take refReact 组件不能接受 ref
【发布时间】:2017-06-17 18:06:29
【问题描述】:

我正在尝试为我在 array.map 上呈现的组件提供一个引用,以便稍后我可以调用这些组件中的一些函数。

同一个组件会有 3 个实例,当给它们一个 ref 时我得到了这个错误:

Uncaught Error: Stateless function components cannot have refs.

这里,父组件的 render 方法试图渲染这 3 个子组件:

render() {
const { strings } = this.props;

const ElementsContainer = ({elements}) => (
  <div className="containerSection">
    {elements.map( (element, i) => {
      return(<div key={"container"+i} className="camaraLentaContainer" id={"camaraLentaContainer" + i}>

        <CamaraLenta ref={"camaraLenta"+i} index={i} images={element.camaraLenta.images}/>

      </div>)
      })
    }
  </div>
)

return (
  <div className="home" >

    <ElementsContainer elements={strings.elements} />

  </div>
);

}

这里是 CamaraLenta(子)组件,非常简化,所以我们可以看到..

import ...;

export default class CamaraLenta extends React.Component {
  static propTypes = {
    name: PropTypes.string,
  };

  static contextTypes = {
    baseUrl: PropTypes.string.isRequired,
    project: PropTypes.string.isRequired
  }

  constructor(props) {
    super(props);

    this.state = {
        slideIndex: 0,
        loading: false,
        imagesTotalDataSrc: [],
        imagesTotalDataLoaded: 0,
        timeoutSlider: null
    };

    this.handleSliderClick = this.handleSliderClick.bind(this);
  }

  componentDidMount() {

  }

    //Touch/Click slider, we kill timeout
    handleSliderClick() {
        clearTimeout(this.state.timeoutSlider);
    }

    registerEvents(){
        $("html, body").on("scroll mousedown wheel DOMMouseScroll mousewheel keyup touchmove", function(){
        $("html, body").stop().unbind('scroll mousedown DOMMouseScroll mousewheel keyup'); 
      });
    }

  render() {
    const {index} = this.props;

    return (
      <div>

        <div className="slidesContainer"> 
            <canvas id={"stage" + index}>
                Tu navegador no soporta canvas
            </canvas>
            <div className="slider" id={"slider" + index} onClick={this.handleSliderClick}></div>

            <Loading visible={this.state.loading}/>
        </div>

      </div>
    );
  }
}`

我的版本:

"react": "^15.5.4",
"react-redux": "^5.0.5",
"redux": "^3.7.0",

【问题讨论】:

  • 如果我删除对我正在渲染的 CamaraLenta 组件的引用,错误就会消失,但我以后不能从父级使用它们,当然......
  • 那是因为无状态函数无权访问这个关键字或引用
  • 我不明白。两个组件都有状态,所以它们不是无状态的。
  • 您的整体组件可能是,但您的 ElementsContainer 是无状态组件

标签: reactjs components


【解决方案1】:

无状态组件不适用于 refs,如果您真的想使用 findDOMNode 解封装组件,请将您的组件转换为基于类的组件或将您的 react 降级到 0.14 之前的任何版本(不推荐)。

此页面中的更多信息,关于他们为什么从无状态组件中删除此功能的讨论https://github.com/facebook/react/issues/4936

【讨论】:

  • 感谢您的回答尤里。这里的事情是我的组件是有状态的,正如你在上面看到的。我使用 this.state = {...} 在构造函数中声明了它。它不再是一种有效的声明状态的方式吗?也许 React 15+ 没有意识到这个组件确实有一个状态?谢谢
  • 哦,你是说父组件?也许没有状态,我现在不确定,因为我没有代码......明天第一件事会检查!
  • 我不明白。两个组件都有状态,所以它们不是无状态的。
【解决方案2】:

好的。正如一些人在答案中所建议的那样,我弄错了。无状态组件/函数是 ElementsContainer,我在渲染函数中声明了它。

最后,我改变了声明我对 this 的引用的方式:

ref={ el => this.camerasRefs.push(el) }

而且,在我的主要组件构造函数中,我这样声明了该变量:

constructor(props) {
    super(props);

    this.state = {
      triggeredSections: []
    };

    this.camerasRefs = [];

  }

所以我终于可以使用这个数组访问我的 CamaraLenta 组件了。

  handleRepeat(index) {
    this.camerasRefs[index].handleRepeat();
  }

感谢您的帮助和理解!

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2021-09-20
    • 1970-01-01
    • 2018-04-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-03-09
    • 1970-01-01
    相关资源
    最近更新 更多