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的状态。
如果我在Parent构造函数中将Parent的this
绑定到handleChildOnClick
,那么我将失去对Child的引用,因此无法调用Child的方法。但是如果我不绑定它,那么我就无法在handleChildOnClick
中设置Parent的状态。
有没有办法绑定this
而不是覆盖原来的this
?
编辑: 我的子组件来自库,所以我无法修改它。
编辑:
我正在使用react-google-maps库。子组件是GoogleMap,每当GoogleMap的getBounds()
回调被触发时,我想在Parent的状态下存储GoogleMap的新视图边界(通过在GoogleMap上调用onBoundsChange
)。
所需的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}
/>)
}
}
您需要从其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}
/>)
}
}
这就是它在单向绑定中起作用的方式。我希望这会有所帮助