is there any way to access the parent component instance in React?
我知道在React组件中能够像
在任何人浪费时间解释它不是功能性的React"方式"之前,了解我需要这个,因为我正在努力实现以下目标:
为Meteor的Spacebars模板引擎构建一个转换器,其渲染模型确实考虑了父组件/模板。
我已经构建了一个修改输出jsx的转换器来实现这一点。 我通过在所有组成的子组件中传入
任何提示将非常感激。
如果你需要从孩子那里访问父母的道具和功能,那没有什么不对。
关键是你不应该使用React内部和未记录的API。
首先,它们可能会改变(破坏你的代码),最重要的是,还有许多其他更清洁的方法。
将道具传递给儿童
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 | class Parent extends React.Component { constructor(props) { super(props) this.fn = this.fn.bind(this) } fn() { console.log('parent') } render() { return <Child fn={this.fn} /> } } const Child = ({ fn }) => <button onClick={fn}>Click me!</button> |
工作实例
使用上下文(如果没有直接的父/子关系)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 | class Parent extends React.Component { constructor(props) { super(props) this.fn = this.fn.bind(this) } getChildContext() { return { fn: this.fn, } } fn() { console.log('parent') } render() { return <Child fn={this.fn} /> } } Parent.childContextTypes = { fn: React.PropTypes.func, } const Child = (props, { fn }) => <button onClick={fn}>Click me!</button> Child.contextTypes = { fn: React.PropTypes.func, } |
工作实例
更新React 0.13及更新版本
替代方案是,从React 16开始,
你已经认识到这几乎不是一件好事,但我在这里重复一遍,因为那些不能很好地阅读这个问题的人:这通常是在React中完成任务的不正当方法。
公共API中没有任何内容可以让您获得所需内容。您可以使用React内部实现此功能,但由于它是私有API,因此可能随时中断。
我再说一遍:你几乎肯定不会在任何生产代码中使用它。
也就是说,您可以使用
这是一个例子:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 | var Parent = React.createClass({ render() { return <Child v="test" />; }, doAThing() { console.log("I'm the parent, doing a thing.", this.props.testing); } }); var Child = React.createClass({ render() { return <button onClick={this.onClick}>{this.props.v}</button> }, onClick() { var parent = this._reactInternalInstance._currentElement._owner._instance; console.log("parent:", parent); parent.doAThing(); } }); ReactDOM.render(<Parent testing={true} />, container); |
这是一个有效的JSFiddle示例:http://jsfiddle.net/BinaryMuse/j8uaq85e/
用React 16测试
我正在玩类似的东西使用上下文,对于读这个的人,对于大多数通常的情况,不建议访问父母!
我创建了一个持有者,在使用时,总是会在显示列表中引用第一个持有者,所以如果你愿意,它就是"父"。看起来像这样:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 | const ParentContext = React.createContext(null); // function to apply to your react component class export default function createParentTracker(componentClass){ class Holder extends React.PureComponent { refToInstance render(){ return( <ParentContext.Consumer> {parent => { console.log('I am:', this, ' my parent is:',parent ? parent.name : 'null'); return( <ParentContext.Provider value={this}> <componentClass ref={inst=>refToInstance=inst} parent={parent} {...this.props} /> </ParentContext.Provider> )} } </ ParentContext.Consumer> ) } } // return wrapped component to be exported in place of yours return Holder; } |
然后使用它,你将反应组件传递给方法,如下所示:
1 2 3 4 5 6 7 8 9 10 | class MyComponent extends React.Component { _doSomethingWithParent(){ console.log(this.props.parent); // holder console.log(this.props.parent.refToInstance); // component } } // export wrapped component instead of your own export default createParentTracker(MyComponent); |
这样,导出函数的任何组件都会将其父级的持有者作为prop传入(如果层次结构中没有任何内容,则为null)。从那里你可以获得refToInstance。在安装完所有内容之前,它将是未定义的。