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

javascript - React.js render subcomponents from component - Stack Overflow

programmeradmin0浏览0评论

I want to create a reusable ponent where the DOM structure can be different each time the ponent is rendered. Let's say I have this

class Comp extends React.Component {
    constructor() {
        super()
        this.state = {
            click: null,
        }
    }
    render() {
        return(
            <div>
                {this.props.chidren}
            </div>
        )
    }
    handleButton1() {
        this.setState({click: 'button1'});
    }
    handleButton2() {
        this.setState({click: 'button2'});
    }
}
class SubComp1 extends React.Component {
    render() {
        return(
            <button onClick={() => this.props.handleButton1()}>Button 1</button>
        )
    }
}
class SubComp2 extends React.Component {
    render() {
        return (
            <button onClick={() => this.props.handleButton2()}>Button 2</button>
        )
    }
}
ReactDOM.render((
<Comp>
    <div id="somediv">
        <div id="andanother">
            <SubComp1 />
        </div>
    </div>
    <div id="andanotherother">
        <SubComp2 />
    </div>
</Comp>), document.getElementById('app'))

Currently, the two subponents do not have access to their respective handler functions. What's the best way of passing the functions handleButton1 and handleButton2 to the subponents assuming that their position in the DOM is dynamic and might change depending on the layout of the page. I have thought of 2 solutions so far:

  1. Iterating inside the props.children until I find the element of interest then clone it with the property

  2. Using ref and somehow render the subponents after the main ponent has been rendered through the ponentDidMount callback.

What are your thoughts on this?

I want to create a reusable ponent where the DOM structure can be different each time the ponent is rendered. Let's say I have this

class Comp extends React.Component {
    constructor() {
        super()
        this.state = {
            click: null,
        }
    }
    render() {
        return(
            <div>
                {this.props.chidren}
            </div>
        )
    }
    handleButton1() {
        this.setState({click: 'button1'});
    }
    handleButton2() {
        this.setState({click: 'button2'});
    }
}
class SubComp1 extends React.Component {
    render() {
        return(
            <button onClick={() => this.props.handleButton1()}>Button 1</button>
        )
    }
}
class SubComp2 extends React.Component {
    render() {
        return (
            <button onClick={() => this.props.handleButton2()}>Button 2</button>
        )
    }
}
ReactDOM.render((
<Comp>
    <div id="somediv">
        <div id="andanother">
            <SubComp1 />
        </div>
    </div>
    <div id="andanotherother">
        <SubComp2 />
    </div>
</Comp>), document.getElementById('app'))

Currently, the two subponents do not have access to their respective handler functions. What's the best way of passing the functions handleButton1 and handleButton2 to the subponents assuming that their position in the DOM is dynamic and might change depending on the layout of the page. I have thought of 2 solutions so far:

  1. Iterating inside the props.children until I find the element of interest then clone it with the property

  2. Using ref and somehow render the subponents after the main ponent has been rendered through the ponentDidMount callback.

What are your thoughts on this?

Share Improve this question edited Jul 12, 2017 at 20:56 Binyuan Sun asked Jul 12, 2017 at 20:31 Binyuan SunBinyuan Sun 1461 silver badge9 bronze badges 1
  • 1 Could you highlight your problem? – divine Commented Jul 12, 2017 at 20:50
Add a ment  | 

3 Answers 3

Reset to default 2

This is a place where using React's Context would be the most straightforward solution.

Another solution would be to use Redux actions, but that would make your ponent less reusable and more tightly coupled with your application, which you may or may not care about.

Why not do something like this:

class Comp extends React.Component {
    constructor() {
        super()
        this.state = {
            click: null,
        }
    }
    render() {
        return(
            <div>
                {this.props.chidren}
            </div>
        )
    }
    handleButton(button) {
        this.setState({click: button});
    }
}

Then in the subponents you can do something like

class SubComp1 extends React.Component {
    render() {
        return(
            <button onClick={() => this.props.handleButton('button1')}>Button 1</button>
        )
    }
}

class SubComp2 extends React.Component {
    render() {
        return (
            <button onClick={() => this.props.handleButton('button2')}>Button 2</button>
        )
    }
}

One Alternative option which might fit your needs is to build a higher order ponent, which decorates another ponent with some additional functionality, below is a quick example of how this may work for you,

The higher order ponent:

const Comp = ComposedComponent =>
  class Comp extends React.Component {
    constructor(props) {
        super(props)
        this.handleButton = this.handleButton.bind(this);
        this.state = {
            click: null,
        }
    }

    handleButton(button) {
      this.setState({click: button}); 
    }

    render() {
        return(
            <ComposedComponent
              onClick={this.handleButton}
            />
        )
    }
  }

  export default Comp;

The child ponent:

class SubComp1 extends React.Component {
    render() {
        return(
            <button onClick={() => this.props.onClick('button1')}>Button 1</button>
        )
    }
}

How to use it:

const ExtendedComp = Comp(SubComp1);

<ExtendedComp />

would this be suitable for your task?

发布评论

评论列表(0)

  1. 暂无评论