如何将状态 true 或 false 从 child 传递到 parent- React
How to pass the state true or false from a child to the parent- React
我有两个组件,一个 parent (Widgets) 和另一个子 (Telefono)。 "Telefono" 组件具有 notInCall
状态,我用它绘制或不绘制代码的特定部分。
另一方面,我在 parent 中有 showComponent()
函数,我用它显示或不显示 child 组件(Telefono)和其他两个组件。
我需要在 the showComponent()
函数中从 parent 恢复 notInCall
的当前状态(真或假),但我不知道该怎么做。
编辑:我觉得我没有解释好。在 child 我使用条件 this.state.notInCall
来显示或不显示部分代码。我需要将 true
或 false
响应传递给 parent。如果{this.state.notInCall ? (some code) : (another code)}
。如果 child 上的 this.state.notInCall
是 true
做一件事,如果是 false
做另一件事
这是我的 parent 组件(小部件)
class Widgets extends Component {
constructor(props) {
super(props);
this.state = {
componente: 1,
//notInCall: false,
};
this.showComponent = this.showComponent.bind(this);
}
showComponent(componentName) {
/*this.setState({
notInCall: false,
});*/
if(this.state.notInCall === false){
this.setState({
componente: Telefono,
addActive: Telefono,
});
alert(this.state.notInCall + ' running? Componente:' + componentName);
console.log(this.state.notInCall);
}else{
alert('verdad');
this.setState({
componente: componentName,
addActive: componentName,
});
}
console.log(this.state.notInCall);
}
renderComponent(){
switch(this.state.componente) {
case "ChatInterno":
return <ChatInterno />
case "HistorialLlamadas":
return <HistorialLlamadas />
case "Telefono":
default:
return <Telefono showComponent={this.showComponent}/>
}
}
render(){
return (
<div id="bq-comunicacion">
<nav>
<ul>
<li><button onClick={() => this.showComponent('Telefono')} id="mn-telefono" className={this.state.addActive === 'Telefono' ? 'active' : ''}><Icon icon="telefono" className='ico-telefono'/></button></li>
<li><button onClick={() => this.showComponent('ChatInterno')} id="mn-chat" className={this.state.addActive === 'ChatInterno' ? 'active' : ''}><Icon icon="chat-interno" className='ico-chat-interno'/></button></li>
<li><button onClick={() => this.showComponent('HistorialLlamadas')} id="mn-llamadas" className={this.state.addActive === 'HistorialLlamadas' ? 'active' : ''}><Icon icon="historial-llamadas" className='ico-historial-llamadas'/></button></li>
</ul>
</nav>
<div className="content">
{ this.renderComponent() }
</div>
</div>
);
}
}
这是我的 child 组件(Telefono)
class Telefono extends Component {
constructor(props) {
super(props);
this.inputTelephone = React.createRef();
["update", "reset", "deleteClickNumber", "closeAlert", "handleKeyPress",].forEach((method) => {
this[method] = this[method].bind(this);
});
this.state = this.initialState = {
notInCall: true,
isRunning: false,
};
}
phoneCall(e){
e.preventDefault();
this.props.showComponent(this.state.notInCall);
if(this.state.inputContent.length < 2){
this.setState({
warningEmptyPhone: true,
});
this.change = setTimeout(() => {
this.setState({
warningEmptyPhone: false
})
}, 5000)
}else if(this.state.inputContent.length >= 2 ){
this.setState({
notInCall: !this.state.notInCall,
isRunning: !this.state.isRunning,
componente: 'Telefono',
},
() => {
this.state.isRunning ? this.startTimer() : clearInterval(this.timer);
//console.log(this.componente);
});
}
}
render(){
return(
<div className="pad sb-content">
{this.state.notInCall
? (
<>
<div className="dial-pad">
<div className="digits">
<Numbers numbers={this.state.numbers}
/>
</div>
</div>
<div className="btn-call call" onClick={this.phoneCall.bind(this)}>
<Icon icon="telefono" className='ico-telefono'/>
<span>LLAMAR</span>
</div>
</>
)
: (
<div className="call-pad">
<div id="ca-number" className="ca-number">{this.state.inputContent}</div>
<TimeElapsed id="timer" timeElapsed={timeElapsed}/>
</div>
)}
</div>
);
}
}
感谢您的帮助
您可以在 parent 中创建句柄,例如:
handleNotInCall (notInCall) {
// handle here
}
并将此句柄传递给 child:
<Telefono handleNotInCall={this.handleNotInCall} />
在child中你这样调用:
this.props.handleNotInCall(<param here>)
更新
在 parent 上:
在 Parent:
- 将
notInCall
置于状态
- 为
notInCall
创建句柄
- 通过child句柄和状态
// state
this.state = {
componente: 1,
notInCall: false,
};
// create a handle
handleNotInCall (notInCall) {
this.setState({notInCall});
}
// pass both for child
<Telefono handleNotInCall={this.handleNotInCall} notInCall={this.state.notInCall}/>
在 child 中,你在哪里:
this.setState({
notInCall: !this.state.notInCall,
isRunning: !this.state.isRunning,
componente: 'Telefono',
})
// change for
this.props.handleNotInCall(!this.props.notInCall)
this.setState({
isRunning: !this.state.isRunning,
componente: 'Telefono',
})
// where you use for compare
this.state.notInCall ?
// change for:
this.props.notInCall ?
如果我没有正确理解你的问题,那么 Marcello Silva 的回答是正确的。
假设你有这个:
class Parent extends React.Component {
constructor(props) {
super(props);
this.state = {
childAvailable: true,
};
}
handleAvailability = status => {
this.setState({ childAvailable: status });
}
render() {
const { childAvailable } = this.state;
if (!childAvailable) {
return (...); // display whatever you want if children not available
} else {
return (
<div>
{children.map(child => {
<Children
child={child}
statusHandler={this.handleAvailability}
/>
}
</div>
);
}
}
}
和
class Children extends React.Component {
constructor(props) {
super(props);
this.state = {
available: true,
};
}
handleClick = e => {
const status = !this.state.available;
this.setState(prevState => { available: !prevState.available });
// if you call the handler provided by the parent here, with the value
// of status, it will change the state in the parent, hence
// trigger a re render conditionned by your value
this.props.statusHandler(status);
}
render() {
return (
<div>
<button onClick={this.handleClick}>Click me to change status</button>
</div>
);
}
}
这样做会在 parent 中调用您作为 prop 传递给 children 的函数。此函数设置您的状态,因此在设置状态后触发重新渲染,因此考虑到 childAvailable
.
的新值,您将渲染您想要的任何内容
编辑:在看到对上述答案的评论后,我想补充一点,您当然可以根据 [=] 上的条件调用 handleClick
方法14=].
我有两个组件,一个 parent (Widgets) 和另一个子 (Telefono)。 "Telefono" 组件具有 notInCall
状态,我用它绘制或不绘制代码的特定部分。
另一方面,我在 parent 中有 showComponent()
函数,我用它显示或不显示 child 组件(Telefono)和其他两个组件。
我需要在 the showComponent()
函数中从 parent 恢复 notInCall
的当前状态(真或假),但我不知道该怎么做。
编辑:我觉得我没有解释好。在 child 我使用条件 this.state.notInCall
来显示或不显示部分代码。我需要将 true
或 false
响应传递给 parent。如果{this.state.notInCall ? (some code) : (another code)}
。如果 child 上的 this.state.notInCall
是 true
做一件事,如果是 false
做另一件事
这是我的 parent 组件(小部件)
class Widgets extends Component {
constructor(props) {
super(props);
this.state = {
componente: 1,
//notInCall: false,
};
this.showComponent = this.showComponent.bind(this);
}
showComponent(componentName) {
/*this.setState({
notInCall: false,
});*/
if(this.state.notInCall === false){
this.setState({
componente: Telefono,
addActive: Telefono,
});
alert(this.state.notInCall + ' running? Componente:' + componentName);
console.log(this.state.notInCall);
}else{
alert('verdad');
this.setState({
componente: componentName,
addActive: componentName,
});
}
console.log(this.state.notInCall);
}
renderComponent(){
switch(this.state.componente) {
case "ChatInterno":
return <ChatInterno />
case "HistorialLlamadas":
return <HistorialLlamadas />
case "Telefono":
default:
return <Telefono showComponent={this.showComponent}/>
}
}
render(){
return (
<div id="bq-comunicacion">
<nav>
<ul>
<li><button onClick={() => this.showComponent('Telefono')} id="mn-telefono" className={this.state.addActive === 'Telefono' ? 'active' : ''}><Icon icon="telefono" className='ico-telefono'/></button></li>
<li><button onClick={() => this.showComponent('ChatInterno')} id="mn-chat" className={this.state.addActive === 'ChatInterno' ? 'active' : ''}><Icon icon="chat-interno" className='ico-chat-interno'/></button></li>
<li><button onClick={() => this.showComponent('HistorialLlamadas')} id="mn-llamadas" className={this.state.addActive === 'HistorialLlamadas' ? 'active' : ''}><Icon icon="historial-llamadas" className='ico-historial-llamadas'/></button></li>
</ul>
</nav>
<div className="content">
{ this.renderComponent() }
</div>
</div>
);
}
}
这是我的 child 组件(Telefono)
class Telefono extends Component {
constructor(props) {
super(props);
this.inputTelephone = React.createRef();
["update", "reset", "deleteClickNumber", "closeAlert", "handleKeyPress",].forEach((method) => {
this[method] = this[method].bind(this);
});
this.state = this.initialState = {
notInCall: true,
isRunning: false,
};
}
phoneCall(e){
e.preventDefault();
this.props.showComponent(this.state.notInCall);
if(this.state.inputContent.length < 2){
this.setState({
warningEmptyPhone: true,
});
this.change = setTimeout(() => {
this.setState({
warningEmptyPhone: false
})
}, 5000)
}else if(this.state.inputContent.length >= 2 ){
this.setState({
notInCall: !this.state.notInCall,
isRunning: !this.state.isRunning,
componente: 'Telefono',
},
() => {
this.state.isRunning ? this.startTimer() : clearInterval(this.timer);
//console.log(this.componente);
});
}
}
render(){
return(
<div className="pad sb-content">
{this.state.notInCall
? (
<>
<div className="dial-pad">
<div className="digits">
<Numbers numbers={this.state.numbers}
/>
</div>
</div>
<div className="btn-call call" onClick={this.phoneCall.bind(this)}>
<Icon icon="telefono" className='ico-telefono'/>
<span>LLAMAR</span>
</div>
</>
)
: (
<div className="call-pad">
<div id="ca-number" className="ca-number">{this.state.inputContent}</div>
<TimeElapsed id="timer" timeElapsed={timeElapsed}/>
</div>
)}
</div>
);
}
}
感谢您的帮助
您可以在 parent 中创建句柄,例如:
handleNotInCall (notInCall) {
// handle here
}
并将此句柄传递给 child:
<Telefono handleNotInCall={this.handleNotInCall} />
在child中你这样调用:
this.props.handleNotInCall(<param here>)
更新
在 parent 上: 在 Parent:
- 将
notInCall
置于状态 - 为
notInCall
创建句柄
- 通过child句柄和状态
// state
this.state = {
componente: 1,
notInCall: false,
};
// create a handle
handleNotInCall (notInCall) {
this.setState({notInCall});
}
// pass both for child
<Telefono handleNotInCall={this.handleNotInCall} notInCall={this.state.notInCall}/>
在 child 中,你在哪里:
this.setState({
notInCall: !this.state.notInCall,
isRunning: !this.state.isRunning,
componente: 'Telefono',
})
// change for
this.props.handleNotInCall(!this.props.notInCall)
this.setState({
isRunning: !this.state.isRunning,
componente: 'Telefono',
})
// where you use for compare
this.state.notInCall ?
// change for:
this.props.notInCall ?
如果我没有正确理解你的问题,那么 Marcello Silva 的回答是正确的。
假设你有这个:
class Parent extends React.Component {
constructor(props) {
super(props);
this.state = {
childAvailable: true,
};
}
handleAvailability = status => {
this.setState({ childAvailable: status });
}
render() {
const { childAvailable } = this.state;
if (!childAvailable) {
return (...); // display whatever you want if children not available
} else {
return (
<div>
{children.map(child => {
<Children
child={child}
statusHandler={this.handleAvailability}
/>
}
</div>
);
}
}
}
和
class Children extends React.Component {
constructor(props) {
super(props);
this.state = {
available: true,
};
}
handleClick = e => {
const status = !this.state.available;
this.setState(prevState => { available: !prevState.available });
// if you call the handler provided by the parent here, with the value
// of status, it will change the state in the parent, hence
// trigger a re render conditionned by your value
this.props.statusHandler(status);
}
render() {
return (
<div>
<button onClick={this.handleClick}>Click me to change status</button>
</div>
);
}
}
这样做会在 parent 中调用您作为 prop 传递给 children 的函数。此函数设置您的状态,因此在设置状态后触发重新渲染,因此考虑到 childAvailable
.
编辑:在看到对上述答案的评论后,我想补充一点,您当然可以根据 [=] 上的条件调用 handleClick
方法14=].