如何从父的构造函数中调用children方法?

时间:2017-11-01 12:18:50

标签: reactjs

用法:

<SegmentedControl activeSegmentKey="c">
    <Segment key="a" label="SegmentA" />
    <Segment key="b" label="SegmentB" />
    <Segment key="c" label="SegmentC" />
</SegmentedControl>

问题是如何从SegmentedControl.constructor()调用Segment.activate方法。

我现在不能这样做,因为props.children的所有孩子都是对象,而不是段。

我知道总有另一种方法可以实现同样的目标。例如,在SegmentedControl.render()期间。

我可以将初始化所需的所有道具(例如活动)传递给Segment child。

另一种方法是将onRef设置为默认的Segment子级。

尽管如此,我想知道如何从父的构造函数中调用children方法,当然,如果在React世界中这是合理的哲学。

class Segment extends Component
{
   // ....

   constructor(props)
   {
       super(props);

       this.state = {
                     isActive: false
       }
    }

   activate = (onoff = true) =>
   {
        this.setState({
                        isActive: onoff
        });
   }

   onClick = (event) =>
   {
       this.context.switchSegment(this);
   };

   render()
   {
       let className = "Segment";

       if (this.state.isActive) {
            className += ' SegmentActive';
       }

       return (
            <div className={className}>
                <a href="#" onClick={this.onClick.bind(this)}><span>{this.props.label}</span></a>
            </div>
        )
    }
}

class SegmentedControl extends Component
{
   // ...

   activeSegment = null;

   constructor(props)
   {
       super(props);

       // ...

       if (this.activeSegment) {
           this.activeSegment.activate(true); // Error! because this.activeSegment is Object
       }
   }

   getChildContext()
   {
        var self = this;
        return {
            switchSegment: (segment) => {
                segment.activate(true); // Ok (segment is Segment)
                self.activeSegment.activate(false); // First call is also bad(self.activeSegment is Object)
                self.activeSegment = segment;
            }
        };
    };

   render()
   {
        return (
            <div className='SegmentedControl'>
                {this.props.children}
            </div>
        )
    }
}    

Live code

Final solution

2 个答案:

答案 0 :(得分:1)

您可以使用cloneElement来实现这一目标:

<div className='SegmentedControl'>
  {React.cloneElement(this.props.children, {
    isActive: YOUR_ACTIVE_RULE,
  }
</div>

答案 1 :(得分:1)

我建议使用合成。

您可以将render() { return <div> {this.props.children.map((child, index) => { return <Segment ref={(ref) => this[index] = ref}> {child} </Segment> } </div> } 渲染更改为以下内容:

<SegmentedControl activeSegmentKey="c">
    <label key="a">SegmentA</label>
    <label key="b">SegmentB</label>
    <label key="c">SegmentC</label>
</SegmentedControl>

这意味着您可以将组件树替换为以下内容:

Windows NT user or group 'IIS APPPOOL\ASP.NET v4.0' not found. Check the name again. (Microsoft SQL Server, Error: 15401)