我有两个部分,父母和孩子。
父母:
class Parent extends React.Component {
constructor(){
super()
this.state = {
select: false
}
}
isSelect(){
this.setState({...this.state, select: !this.state.select})
}
render(){
const { Header, children } = this.props
return (
<>
<Header isSelect={this.isSelect} />
</>
)
}
}
孩子:
class Child extends React.Component {
render(){
const {title, isSelect} = this.props
/*problem here! can not get isSelect*/
return(
<div>
<p>{title}</p>
<button onClick={this.isSlect}>choose</button>
/*problem here! isSelect*/
</div>
)
}
}
使用中:
<Parent Header={<Child title='just for test' />} />
可以渲染组件,但不能渲染单击事件。
我想为子组件自动设置isSlect
函数,因为它只是调用父函数并恢复布尔值。因此再次使用它没有意义。
问题是如何通过此isSelect
?似乎isSelect={this.isSelect}
已被<Header isSelect={this.isSelect} />
覆盖。
答案 0 :(得分:1)
您可以将Header
的行为更改为通过参数传递isSelect
回调的函数:
render() {
const { Header, children } = this.props
return Header(this.isSelect)
}
组件现在可以根据需要分配接收的功能:
<Parent Header={clicked => <Child title='just for test' isSelect={clicked} />} />
工作示例:
class Parent extends React.Component {
constructor(props) {
super(props) //Don't forget to send the props in super
this.state = {
select: false
}
}
isSelect = () => { //Arrow function to avoid having to bind it
this.setState({ ...this.state, select: !this.state.select })
console.log('Selected')
}
render() {
const { Header, children } = this.props
return Header(this.isSelect)
}
}
class Child extends React.Component {
render() {
const { title, isSelect } = this.props
return (
<div>
<p>{title}</p>
<button onClick={isSelect}>choose</button> {/* Careful, you do not need to add 'this.' */}
</div>
)
}
}
ReactDOM.render(<Parent Header={clicked => <Child title='just for test' isSelect={clicked} />} />, document.getElementById('root'))
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.6.1/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.6.1/umd/react-dom.production.min.js"></script>
<div id='root'>
答案 1 :(得分:0)
JS类方法默认情况下不受约束,因此,如果像在代码中那样传递isSelect
,则this
将是未定义的(而this.setState
将不起作用)。 / p>
您可以将调用isSelect
的匿名欠款函数传递给子项:
<Child isSelect={() => this.isSelect()} />
或将其绑定在Parent
建设者中:
this.isSelect = this.isSelect.bind(this)
或使用public class fields(如果您使用Babel或其他一些编译器,它们仍处于试验阶段):
class Parent extends React.Component {
…
isSelect = () => {
this.setState(…)
}
}
工作示例:
class Parent extends React.Component {
constructor(){
super()
this.state = {
select: false
}
this.isSelect = this.isSelect.bind(this)
}
isSelect(){
this.setState({...this.state, select: !this.state.select})
}
render(){
const { Header, children } = this.props
return (
<div>
<Child isSelect={this.isSelect} />
<Child isSelect={() => this.isSelect()} /> {/* this one will work even without .bind in the constructor */}
<code>{JSON.stringify(this.state, null, 2)}</code>
</div>
)
}
}
class Child extends React.Component {
render(){
return(
<div>
<button onClick={this.props.isSelect}>choose</button>
</div>
)
}
}
ReactDOM.render(
(<Parent/>),
document.querySelector("#root")
);
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.6.3/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.6.3/umd/react-dom.production.min.js"></script>
<div id="root"></div>