2017-04-25 117 views
6

我没有试图做任何hacky使用refs。我只需要元素的ref,因为元素是一个画布,并且在画布上绘制需要它的参考。React - 获取父组件中存在的ref参数

class Parent extends Component { 
    clickDraw =() => { 
    // when button clicked, get the canvas context and draw on it. 
    // how? 
    } 

    render() { 
    return (
     <div> 
     <button onClick={this.clickDraw}> Draw </button> 
     <Child /> 
     </div> 
    ); 
    } 
} 


class Child extends Component { 
    componentDidMount() { 
    const ctx = this.canvas.getContext('2d'); 
    // draw something on the canvas once it's mounted 
    ctx.fillStyle = "#FF0000"; 
    ctx.fillRect(0,0,150,75); 
    } 

    render() { 
    return (
     <canvas width={300} 
       height={500} 
       ref={canvasRef => this.canvas = canvasRef}> 
     </canvas> 
    ); 
    } 
} 

=====

东西我想(这在技术上的作品,但觉得很奇怪),是在父定义<canvas>,所以在它的引用功能,this指父组件。然后我把<canvas>this.canvas作为两个独立的道具传递给孩子。我将<canvas>(名为this.props.canvasJSX)返回到子项的渲染函数中,并且我使用this.canvas(名为this.props.canvasRef)获取其上下文来绘制它。见下:

class Parent extends Component { 
    clickDraw =() => { 
    // now I have access to the canvas context and can draw 
    const ctx = this.canvas.getContext('2d'); 
    ctx.fillStyle = "#00FF00"; 
    ctx.fillRect(0,0,275,250); 
    } 

    render() { 
    const canvas = (
     <canvas width={300} 
       height={500} 
       ref={canvasRef => this.canvas = canvasRef}> 
     </canvas> 
    ); 
    return (
     <div> 
     <button onClick={this.clickDraw}> Draw </button> 
     <Child canvasJSX={canvas} 
       canvasRef={this.canvas} /> 
     </div> 
    ); 
    } 
} 


class Child extends Component { 
    componentDidMount() { 
    const ctx = this.props.canvasRef.getContext('2d'); 
    // draw something on the canvas once it's mounted 
    ctx.fillStyle = "#FF0000"; 
    ctx.fillRect(0,0,150,75); 
    } 

    render() { 
    return this.props.canvas; 
    } 
} 

有没有更实际的标准方法?

+0

可能的重复[如何访问父组件中的子组件的引用>](https://stackoverflow.com/questions/37647061/how-do-i-access-refs-of-a-child -component-in-the-parent-component) – arpl

+0

请在父组件中使用getter和setter – zloctb

回答

4

你实际上应使用第一种方法,你可以在父

class Parent extends Component { 
    clickDraw =() => { 
    // when button clicked, get the canvas context and draw on it. 
    const ctx = this.childCanvas.canvas.getContext('2d'); 
    ctx.fillStyle = "#00FF00"; 
    ctx.fillRect(0,0,275,250); 
    } 

    render() { 
    return (
     <div> 
     <button onClick={this.clickDraw}> Draw </button> 
     <Child ref={(ip) => this.childCanvas = ip}/>; 
     </div> 
    ); 
    } 
} 


class Child extends Component { 
    constructor() { 
    super(); 
    this.canvas = null; 
    } 
    componentDidMount() { 
    const ctx = this.canvas.getContext('2d'); 
    // draw something on the canvas once it's mounted 
    ctx.fillStyle = "#FF0000"; 
    ctx.fillRect(0,0,150,75); 
    } 

    render() { 
    return (
     <canvas width={300} 
       height={500} 
       ref={canvasRef => this.canvas = canvasRef}> 
     </canvas> 
    ); 
    } 
} 

只能用这种方式访问​​子元素裁判是子组件被声明为class

+0

谢谢!除了轻微的拼写错误('refs'应该是'ref')之外我完成了一个完美的编辑。 – tscizzle

+0

Shubham我不确定如何为多个HTML元素[我的项目]执行此实现(https://stackblitz.com/edit/react-pulnct?file=Posts.js) – Omar

+1

@Omar,编辑您的代码片段选中此项https://stackblitz.com/edit/react-yqcgey?file=Posts.js –

0

如果不能避免从React docs萃取。将所建议的模式:

import React, {Component} from 'react'; 

const Child = ({setRef}) => <input type="text" ref={setRef} />; 

class Parent extends Component { 
    constructor(props) { 
     super(props); 
     this.setRef = this.setRef.bind(this); 
    } 
    componentDidMount() { 
     // Call function on Child dom element 
     this.childInput.focus(); 
    } 
    setRef(input) { 
     this.childInput = input; 
    } 
    render() { 
     return <Child setRef={this.setRef} /> 
    } 
} 

传递势必this一个函数作为支柱。 React将拨打儿童ref回拨setRef并将childInput属性附加到this,正如我们已经注明的那样,指向