简体   繁体   English

从子组件中反应访问父节点的dom节点

[英]React access parent's dom node from child component

I have a grid component as follow: 我有一个网格组件如下:

import React, { Component } from 'react';

import Action from './action.jsx';

class Grid extends Component {

    constructor(props) {
        super(props);
        this.maxN = 110;
        this.tempArray = [];
        this.question;
    }

    getRandomN() {
        var randomN = Math.floor((Math.random() * this.maxN) + 1);

        if(this.tempArray.indexOf(randomN) === -1) {
            this.tempArray.push(randomN);
        }
        else {
            randomN = this.getRandomN();
        }

        return randomN;
    }

    getRandomQuestion() {   
        this.question = this.props.current.data.questions[this.getRandomN()];
        return this.question;
    }

    render() {
        this.getRandomQuestion();

        return (
            <section className="game">
                <div className="grid">

                    <div className="row">
                        <div ref="n1"></div>
                        <div ref="n2"></div>
                        <div ref="n3"></div>
                        <div ref="n4"></div>
                        <div ref="n5"></div>
                        <div ref="n6"></div>
                    </div>

                    <div className="row">
                        <div ref="n7"></div>
                        <div ref="n8"></div>
                        <div ref="n9"></div>
                        <div ref="n10"></div>
                        <div ref="n11"></div>
                        <div ref="n12"></div>
                    </div>

                    <div className="row">
                        <div ref="n13"></div>
                        <div ref="n14"></div>
                        <div ref="n15"></div>
                        <div ref="n16"></div>
                        <div ref="n17"></div>
                        <div ref="n18"></div>
                    </div>

                    <div className="row">
                        <div ref="n19"></div>
                        <div ref="n20"></div>
                        <div ref="n21"></div>
                        <div ref="n22"></div>
                        <div ref="n23"></div>
                        <div ref="n24"></div>
                    </div> 
                </div>

                <Action question={this.question} getRandomQuestion={this.getRandomQuestion.bind(this)}/>
            </section>
        );
    }
}

export default Grid;

inside the "Action" component, based on the correct or wrong answer coming from "getNewQuestion" I need to access a random grid element from the grid component. 在“Action”组件内部,基于来自“getNewQuestion”的正确或错误答案,我需要从网格组件访问随机网格元素。 (any random going from "n1" to "n24" as assigned to each ref attribute) (任何随机从“n1”到“n24”分配给每个ref属性)

import React, { Component } from 'react';

class Action extends Component {
    constructor(props) {
        super(props);

        this.state = {
            question: props.question
        }
    }

    getNewQuestion(e) {
        console.log(this.state.question.correct_option);

        let answerId = "option_" + this.state.question.correct_option;

        if(e.target.getAttribute('data-question') == answerId) {
            this.setState({
                question: this.props.getRandomQuestion()
            });
        }
        else {
            console.log('wrong');

            React.findDOMNode(this.refs.n1).classList.add('fdsdfsdfsdfsdfsfsdf');
        }
    }

    render() {
        let state = this.state;

        return(
            <div className="action">
                <div className="action-question">
                    <h3>{state.question.question}</h3>
                </div>

                <div className="action-answers">
                    <p data-question="option_1" onClick={this.getNewQuestion.bind(this)}>{state.question.option_1}</p>
                    <p data-question="option_2" onClick={this.getNewQuestion.bind(this)}>{state.question.option_2}</p>
                    <p data-question="option_3" onClick={this.getNewQuestion.bind(this)}>{state.question.option_3}</p>
                    <p data-question="option_4" onClick={this.getNewQuestion.bind(this)}>{state.question.option_4}</p>
                </div>
            </div>
        );
    }
}   

export default Action;

inside the "if" statment of the "getNewQuestion" I would like to do something like: 在“getNewQuestion”的“if”语句中,我想做类似的事情:

n2.classList.addClass('hidden'); n2.classList.addClass( '隐藏');

I can't figure out how to access a parent's dom node from the "Action" component 我无法弄清楚如何从“Action”组件访问父节点的dom节点

Does the child really need to access the parent DOM directly? 孩子真的需要直接访问父DOM吗? Shouldn't the parent Component know how to present itself? 父组件不应该知道如何呈现自己吗? If so, then you can use callbacks that you pass down to the children, so that the children have the possibility to notify the parent when it should change. 如果是这样,那么您可以使用传递给子节点的回调,以便子节点可以在它应该更改时通知父节点。

const Child = ({modifyParent}) => (
  <div onClick={ modifyParent } >Click me!</div>
);

const Parent = () => {
  const modifyMyOwnStyle = event => {
    // here you have easy access 
    // if you want to style the parent.
    alert('Modifying style, based on child call');
  }

  return (
    <Child modifyParent={ modifyMyOwnStyle }/>
  );
};

ReactDOM.render(<Parent />, document.getElementById('root'));

Runnable JSFiddle demo here 这里有 Runnable JSFiddle演示

You can get the ref of a component and pass this to its children like so: 您可以获取组件的引用并将其传递给其子代,如下所示:

render() {
  return (
    <div ref={node => this.node = node}>
      <SomeChild parent={this.node} />
    </div>
  )
}

read more about it here: https://facebook.github.io/react/docs/refs-and-the-dom.html 在这里阅读更多相关信息: https//facebook.github.io/react/docs/refs-and-the-dom.html

However I have to say that doing this is usually a bad idea, and I would reconsider if you really need to pass the node, or if there is another way around the problem. 但是我不得不说这样做通常是一个坏主意,如果你真的需要通过节点,或者如果有另一种解决问题的办法,我会重新考虑。

EDIT: As jonahe's comment shows you can usually get around the problem by passing a callback to the child component that you can fire when something needs to happen in the parent component 编辑:正如jonahe的评论所示,您通常可以通过将回调传递给子组件来解决问题,当父组件中需要发生某些事情时您可以触发该组件

Better than accessing parent's DOM node directly, you can use a callback prop that does it for you. 比直接访问父节点的DOM节点更好,您可以使用为您执行此操作的回调道具。

Something like: 就像是:

class Grid extends Component {
  constructor(props) {
    super(props)

    this.accessRandomElement = this.accessRandomElement.bind(this)
  }

  accessRandomElement() {
    // do you thing
  }

  render() {
    this.getRandomQuestion()

    return (
      <section className="game">
        ...
        <Action
          question={this.question}
          onAccessYourRandomElement={this.accessRandomElement}
          ///
        />
      </section>
    )
  }
}

and then from inside Action you call this.props.onAccessYourRandomElement() 然后从Action内部调用this.props.onAccessYourRandomElement()

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM