2017-04-25 119 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,正如我們已經註明的那樣,指向