最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - React - passing ref to sibling - Stack Overflow

programmeradmin2浏览0评论

I need to have 2 sibling components, and 1 of them has to have a reference to another - is that possible?

I tried this:

<button ref="btn">ok</button>
<PopupComponent triggerButton={this.refs.btn} />

And even this

<button ref="btn">ok</button>
<PopupComponent getTriggerButton={() => this.refs.btn} />

But I get undefined in both situations. Any ideas?

Note: a parent component will not work for me, because I need to have multiple sets of those, like

<button />
<PopupComponent />
<button />
<PopupComponent />
<button />
<PopupComponent />

NOT like this:

<div>
  <button />
  <PopupComponent />
</div>
<div>
  <button />
  <PopupComponent />
</div>
<div>
  <button />
  <PopupComponent />
</div>

I need to have 2 sibling components, and 1 of them has to have a reference to another - is that possible?

I tried this:

<button ref="btn">ok</button>
<PopupComponent triggerButton={this.refs.btn} />

And even this

<button ref="btn">ok</button>
<PopupComponent getTriggerButton={() => this.refs.btn} />

But I get undefined in both situations. Any ideas?

Note: a parent component will not work for me, because I need to have multiple sets of those, like

<button />
<PopupComponent />
<button />
<PopupComponent />
<button />
<PopupComponent />

NOT like this:

<div>
  <button />
  <PopupComponent />
</div>
<div>
  <button />
  <PopupComponent />
</div>
<div>
  <button />
  <PopupComponent />
</div>
Share Improve this question edited Mar 22, 2016 at 23:00 Felix Kling 816k180 gold badges1.1k silver badges1.2k bronze badges asked Mar 22, 2016 at 18:58 ZiarnoZiarno 7,5625 gold badges37 silver badges41 bronze badges 4
  • Can I ask why the second alternative is not a viable solution in your case? Because that's exactly how I'd solve this kind of problem. – Nico Commented Mar 22, 2016 at 19:12
  • well I guess it's mostly just css reasons... I'm using semantic-ui - the PopupComponent is actually either display:none; or position:absolute; and have a parent on those 2 really messes everything up... – Ziarno Commented Mar 22, 2016 at 19:26
  • So you're just using the ref to show / hide the PopupComponent? – Mark McKelvy Commented Mar 22, 2016 at 20:35
  • yes. After some fiddling I'll use the parent after all I think – Ziarno Commented Mar 22, 2016 at 20:53
Add a comment  | 

4 Answers 4

Reset to default 8

Think this question is best answered by the docs:

If you have not programmed several apps with React, your first inclination is usually going to be to try to use refs to "make things happen" in your app. If this is the case, take a moment and think more critically about where state should be owned in the component hierarchy. Often, it becomes clear that the proper place to "own" that state is at a higher level in the hierarchy. Placing the state there often eliminates any desire to use refs to "make things happen" – instead, the data flow will usually accomplish your goal.

Not sure exactly what you are trying to do, but my hunch is a parent component and passing props is what you really want here.

I completely agree with the quote Mark McKelvy has provided. What you are trying to achieve is considered an anti-pattern in React.

I'll add that creating a parent component doesn't necessarily means it has to be a direct parent, you can create a parent component further up the chain, in which you can render an array of all your children components together, having the logic to coordinate between all the children (or pairs of children according to your example) sit inside your parent.

I created a rough example of the concept which should do the trick:

class A extends React.Component {
    onClick(key) {
        alert(this.refs[key].refs.main.innerText);
    }

    render() {
        var children = [];
        for (var i = 0; i < 5; i++)
            children.push.apply(children, this.renderPair(i));

        return (
            <div>
                {children}
            </div>
        );
    }

    renderPair(key) {
        return [
            <B ref={'B' + key} key={'B' + key} onClick={this.onClick.bind(this, 'C' + key)}/>,
            <C ref={'C' + key} key={'C' + key} onClick={this.onClick.bind(this, 'B' + key)}/>
        ];
    }
}

class B extends React.Component {
    render() {
        return <p ref="main" onClick={this.props.onClick}>B</p>;
    }
}

class C extends React.Component {
    render() {
        return <p ref="main" onClick={this.props.onClick}>C</p>;
    }
}


React.render(<A/>, document.getElementById('container'));

And any state you need to save for all your children, you do in the common parent. I really hope this helps.

The following code helps me to setup communication between two siblings. The setup is done in their parent during render() and componentDidMount() calls. Hope it helps.

class App extends React.Component<IAppProps, IAppState> {
    private _navigationPanel: NavigationPanel;
    private _mapPanel: MapPanel;

    constructor() {
        super();
        this.state = {};
    }

    // `componentDidMount()` is called by ReactJS after `render()`
    componentDidMount() {
        // Pass _mapPanel to _navigationPanel
        // It will allow _navigationPanel to call _mapPanel directly
        this._navigationPanel.setMapPanel(this._mapPanel);
    }

    render() {
        return (
            <div id="appDiv" style={divStyle}>
                // `ref=` helps to get reference to a child during rendering
                <NavigationPanel ref={(child) => { this._navigationPanel = child; }} />
                <MapPanel ref={(child) => { this._mapPanel = child; }} />
            </div>
        );
    }
}

special-props

Special Props Warning Most props on a JSX element are passed on to the component, however, there are two special props (ref and key) which are used by React, and are thus not forwarded to the component.

For instance, attempting to access this.props.key from a component (eg. the render function) is not defined. If you need to access the same value within the child component, you should pass it as a different prop (ex: ). While this may seem redundant, it's important to separate app logic from reconciling hints.

发布评论

评论列表(0)

  1. 暂无评论