我尝试做的是从子元素中调用父元素中定义的函数,但将this
绑定到调用函数的子元素,而不是函数运行的父元素。“ p>
有没有办法做到这一点,如果是这样,这会是反模式吗?谢谢。
传递给孩子的家长功能
onSelect = (event => {
// Some code where `this` is the scope of the child calling the function
// Not the scope of the parent where the function is defined
}
家长渲染功能
render() {
return (
<Child onSelect={this.onSelect} />
)
}
儿童渲染功能
render() {
return (
<button onClick={this.props.onSelect.bind(this)} />
)
}
答案 0 :(得分:2)
有没有办法做到这一点,如果是这样,这会是反模式吗?
传递函数(不是箭头函数),并将其绑定在构造函数中。
这是一种反模式,因为父母需要知道孩子的内心工作,这会打破封装。
你是如何做到的:
使用标准方法,而不是箭头功能:
onSelect(e) {
this.setState({
selected: !!e.target.value
});
}
在构造函数中绑定方法:
constructor(props) {
super(props);
this.state = {
selected: false
};
this.onSelect = this.props.onSelect.bind(this);
}
工作示例:
const { Component } = React;
class Child extends Component {
constructor(props) {
super(props);
this.state = {
selected: false
};
this.onSelect = this.props.onSelect.bind(this);
}
render() {
const {selected} = this.state;
return (
<div>
<input onSelect={this.onSelect} defaultValue="I'm the text" />
<div>{selected ? 'selected' : 'not selected'}</div>
</div>
);
}
}
class Parent extends Component {
onSelect(e) {
this.setState({
selected: !!e.target.value
});
}
render() {
return (
<Child onSelect={this.onSelect} />
)
}
}
ReactDOM.render(
<Parent />,
demo
);
&#13;
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.min.js"></script>
<div id="demo"></div>
&#13;
答案 1 :(得分:1)
问题是您将onSelect
定义为箭头函数,因此它会关闭this
,而不是使用调用它的this
。只需将其设为方法或非箭头功能:
class Parent extends React.Component {
onSelect() {
console.log(this.constructor.name);
console.log(this.note);
}
render() {
return <Child onSelect={this.onSelect} />;
}
}
class Child extends React.Component {
constructor(...args) {
super(...args);
this.note = "I'm the child";
}
render() {
return (
<button onClick={this.props.onSelect.bind(this)}>Click Me</button>
);
}
}
ReactDOM.render(
<Parent />,
document.getElementById("root")
);
<div id="root"></div>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.min.js"></script>
但您可以考虑将onSelect
绑定一次而不是重复绑定{例如,不在render
中),也许在Child
的构造函数中。但是,只有将render
称为批次才真正重要。 E.g:
class Parent extends React.Component {
onSelect() {
console.log(this.constructor.name);
console.log(this.note);
}
render() {
return <Child onSelect={this.onSelect} />;
}
}
class Child extends React.Component {
constructor(...args) {
super(...args);
this.note = "I'm the child";
this.onSelect = this.props.onSelect.bind(this);
}
render() {
return (
<button onClick={this.onSelect}>Click Me</button>
);
}
}
ReactDOM.render(
<Parent />,
document.getElementById("root")
);
<div id="root"></div>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.min.js"></script>