【问题标题】:Update parent component state with a function whose arguments rely on child component使用参数依赖于子组件的函数更新父组件状态
【发布时间】:2021-02-18 12:18:24
【问题描述】:

我知道它似乎类似于 That question 的副本,但事实并非如此,我需要做一些稍微不同但不起作用的事情。

我正在实施:

  • 一个组件<Page/>,它有两个子组件:
    • <Greetings/> 消息。
    • <LoginButton/> 按钮。

<Page/> 具有{isLogged: false} 状态。当isLogged 为真/假时,<Greetings/> 应该显示不同的消息。

当isLogged 为假时,<LoginButton/> 应该有一个login 文本,否则为logout,并实现一个从其父组件<Page/> 更新isLogged 状态的函数。

有了这个实现,我愿意学习:

  • <Greetings/>: 如何实现一个子组件,其 props 绑定到父组件状态(有效)
  • <LoginButton/>:如何从子组件更新父组件的状态,通过其 props 为子组件传递父组件的 setState(不工作)。

这是我的源代码:

import React from 'react';
import ReactDOM from 'react-dom';


class Greetings extends React.Component{
  render(){
    if(this.props.isLogged){
      return <p>You're logged. Welcome Back!</p>
    }
    return <p>You're not logged. Please Login</p>
  }
}

class LoginButton extends React.Component{
  login(){
    console.log(this.props)
    this.props.handler({isLogged: true})
  }

  logout(){
    this.props.handler({isLogged: false})
  }
  
  render(){
    if(this.props.isLogged){
      return <button onClick = {()=>{this.logout()}}>logout</button> 
    }
    return <button onClick = {()=>{this.login()}}>login</button>
  }
}

class Page extends React.Component{
  constructor(props){
    super(props)
    this.state = {isLogged: false}
  }

  handler(newState){
    this.setState(newState)
    console.log(this.state)
  }

  render(){
    return(
      <>
      <Greetings isLogged={this.state.isLogged}/>
      <LoginButton isLogged={this.state.isLogged} handler = {()=>this.handler}/>
      </>
    )
  }
}

const element = <Page/>
ReactDOM.render(element, document.getElementById('root'))

我的代码与其他 StackOverflow 问题中的大多数示例之间的主要区别在于,由子组件 &lt;LoginButton/&gt; 决定调用 this.render 的参数,这给我带来了问题。

我认为 login() 和 logout() 函数有问题,但我无法发现是什么。

页面呈现,但按钮不起作用。请帮帮我。

【问题讨论】:

    标签: javascript reactjs


    【解决方案1】:

    这是因为您在 this.handle 中期望和参数,但没有从道具传递值。这应该可以解决您的问题。

    class Page extends React.Component{
      constructor(props){
        super(props)
        this.state = {isLogged: false}
      }
    
      handler(newState){
        console.log(newState)
        this.setState(newState)
      }
    
      render(){
        return(
          <>
          <Greetings isLogged={this.state.isLogged}/>
          <LoginButton handler = {(newState) => this.handler(newState)}/>
          </>
        )
      }
    }
    

    或者你也可以通过绑定你的处理函数并简单地将它作为道具传递给子组件来做到这一点,而不是调用它。

    class Pageextends React.Component{
      constructor(props){
        super(props)
        this.state = {isLogged: false}
        this.handler = this.handler.bind(this);
      }
    
      handler(newState){
        console.log(newState)
        this.setState(newState)
      }
    
      render(){
        return(
          <>
          <Greetings isLogged={this.state.isLogged}/>
          <LoginButton handler = {this.handler}/>
          </>
        )
      }
    }
    

    【讨论】:

    • 也谢谢你!我更喜欢箭头函数而不是绑定,但我明白为什么有些人可能更喜欢其他方式
    • 是的,我也喜欢箭头函数
    【解决方案2】:

    你在这一行提供参数

     this.props.handler({isLogged: true})
    

    但未在传递给 LoginButton 组件的处理程序道具中接收 Page 组件的 render 方法应该是这样的:

     render(){
        return(
          <>
          <Greetings isLogged={this.state.isLogged}/>
          <LoginButton isLogged={this.state.isLogged} handler = {(newState)=>this.handler(newState)}/>
          </>
        )
      }
    

    【讨论】:

      猜你喜欢
      • 2021-06-30
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-06-03
      • 2021-07-06
      • 2017-09-28
      • 2020-08-09
      • 1970-01-01
      相关资源
      最近更新 更多