class Parent extends React.Component {
constructor(props) {
super(props)
this.handleChildOnClick = this.handleChildOnClick.bind(this)
}
handleChildOnClick() {
/* I would like to do something here that requires both Child and Parent.
* But 'this' points to Parent because I binded it in Parent's constructor.
*/
}
render() {
return(
<Child
onClick={this.handleChildOnClick}
/>)
}
}
在handleChildOnClick
回调中,我想调用Child的方法来检索一些数据并相应地更新Parent的状态。
如果我在Parents构造函数中将Parent的this
绑定到handleChildOnClick
,那么我将丢失对Child的引用,因此无法调用Child的方法。但是,如果我不绑定它,那么我将无法在handleChildOnClick
内设置Parent的状态。
有没有办法绑定this
而不覆盖原始的this
吗?
编辑:
我的孩子组件来自图书馆,所以我无法对其进行修改。
编辑:
我正在使用react-google-maps库。子组件是GoogleMap,每当触发GoogleMap的getBounds()
回调函数时,我都想以Parent的状态(通过在GoogleMap上调用onBoundsChange
)存储GoogleMap的新视图范围。 / p>
答案 0 :(得分:2)
您需要从子组件的props中调用处理程序并更新其父状态:
class Parent extends React.Component {
handleChildOnClick = (data) => {
/* I would like to do something here that requires both Child and Parent.
* But 'this' points to Parent because I binded it in Parent's constructor.
*/
}
render() {
return(
<Child
handleChildOnClick={this.handleChildOnClick}
/>)
}
}
然后在您的子组件中:
class Child extends React.Component {
handleChildOnClick = () => {
// you can even send data to parent click handler
this.props.handleChildOnClick(data); // pass any arguments
}
render() {
return(
<button
onClick={this.handleChildOnClick}
/>)
}
}
这就是它在React的PNE方式绑定中的工作方式。 我希望这会有所帮助
答案 1 :(得分:2)
不将所需的this
视为Child
上下文。该函数作为回调传递,它带有一些动态this
。如果this
是Child
组件实例,那只是一个巧合。
该问题特定于不包含现代JS OOP且依赖于任意动态this
而不是将所有必需的数据作为函数参数传递的传统或设计不良的库。一个著名的示例是D3库。
一个函数不能有两个this
。流行的解决方法是结合常规功能(而非箭头)使用self = this
技巧。但是,这在类语法上变得笨拙,因为它不能放在constructor
之外:
class Parent extends React.Component {
constructor(props) {
super(props)
const self = this;
this.handleChildOnClick = function handleChildOnClick() {
// `self` is Parent instance
// `this` is dynamic context
};
}
render() {
return(
<Child
onClick={this.handleChildOnClick}
/>)
}
}
这种改组很不方便,因为通常期望this
是JS OOP中的类实例。
如this related answer中所述,解决此问题的一种方法是提供辅助函数,该辅助函数在内部执行此技巧并将动态上下文映射到函数参数:
function contextWrapper(fn) {
const self = this;
return function (...args) {
return fn.call(self, this, ...args);
}
}
class Parent extends React.Component {
constructor(props) {
super(props)
this.handleChildOnClick = contextWrapper(this.handleChildOnClick.bind(this));
}
handleChildOnClick(context) {
// `this` is Parent instance
// `context` parameter is dynamic context
}
}
render() {
return(
<Child
onClick={this.handleChildOnClick}
/>)
}
}