Reactjs 从子组件更改状态

Reactjs 从子组件更改状态,reactjs,state,Reactjs,State,探索反动和我遇到了一个难题。我有一个子组件,它包含一个TextField组件和一个Button组件: class LoginForm extends Component { constructor(props,context){ super(props,context) this.loginUser = this.loginUser.bind(this); } loginUser(){ this.setState({ errorflage: tru

探索反动和我遇到了一个难题。我有一个子组件,它包含一个TextField组件和一个Button组件:

class LoginForm extends Component {
  constructor(props,context){
    super(props,context)
    this.loginUser = this.loginUser.bind(this);
  }
  loginUser(){
    this.setState({
      errorflage: true,
      errormsg: "This is a required Field"
    })
  }
  render(){
    return(
      <Panel width="375" height="0" halign="center" valign="center">
        <h3>Please Sign In</h3>
        <TextField type="text" label="Email Address:" id="emailaddress" name="emailaddress" focus/>
        <TextField type="password" label="Password:" id="password" name="password"/>
        <LoginButton size="small" proc={this.loginUser}/>
      </Panel>
    )
  }
}
export default LoginForm
类LoginForm扩展组件{
构造函数(道具、上下文){
超级(道具、背景)
this.loginUser=this.loginUser.bind(this);
}
登录用户(){
这是我的国家({
没错,
errormsg:“这是必填字段”
})
}
render(){
返回(
请登录
)
}
}
导出默认登录表单
文本字段组件:

export const TextField = class TextField extends Component {
  constructor(props){
    super(props);
    this.state = {
      errorflag: false,
      errormsg: ""
    }
    this.myRef = React.createRef();
  }
  componentDidMount(){
    if(this.props.focus){
      this.myRef.current.focus();
    }
  }
  render(){
    var errid = this.props.id + "_errmsg";
    var labelStyle = "w3-label-font";
    var inputStyle = "w3-input w3-border w3-light-grey w3-round";
    return(
      <div>
        <label className={labelStyle}><b>{this.props.label}</b></label>
        <input className={inputStyle} type={this.props.type} id={this.props.id} name={this.props.name} ref={this.myRef}/>
        <div id={errid} className="error-msg">{this.state.errormsg}</div>
      </div>
    );
  };
}
export const Button = class Button extends Component {
  render() {
    var css= "w3-btn w3-app-button w3-round";
    css += (this.props.size) ? " w3-"+this.props.size : "";
    return (
      <button onClick={this.props.proc} className={css}>{this.props.children}</button>
    );
  }
}
export const LoginButton = class LoginButton extends Component{
  render(){
    return(
      <Button proc={this.props.proc} size={this.props.size}>Sign In</Button>
    )
  }
}
export const TextField=类TextField扩展组件{
建造师(道具){
超级(道具);
此.state={
errorflag:false,
errormsg:“
}
this.myRef=React.createRef();
}
componentDidMount(){
如果(这个。道具。焦点){
this.myRef.current.focus();
}
}
render(){
var errid=this.props.id+“_errmsg”;
var labelStyle=“w3标签字体”;
var inputStyle=“w3输入w3边框w3浅灰色w3圆形”;
返回(
{this.props.label}
{this.state.errormsg}
);
};
}
按钮组件:

export const TextField = class TextField extends Component {
  constructor(props){
    super(props);
    this.state = {
      errorflag: false,
      errormsg: ""
    }
    this.myRef = React.createRef();
  }
  componentDidMount(){
    if(this.props.focus){
      this.myRef.current.focus();
    }
  }
  render(){
    var errid = this.props.id + "_errmsg";
    var labelStyle = "w3-label-font";
    var inputStyle = "w3-input w3-border w3-light-grey w3-round";
    return(
      <div>
        <label className={labelStyle}><b>{this.props.label}</b></label>
        <input className={inputStyle} type={this.props.type} id={this.props.id} name={this.props.name} ref={this.myRef}/>
        <div id={errid} className="error-msg">{this.state.errormsg}</div>
      </div>
    );
  };
}
export const Button = class Button extends Component {
  render() {
    var css= "w3-btn w3-app-button w3-round";
    css += (this.props.size) ? " w3-"+this.props.size : "";
    return (
      <button onClick={this.props.proc} className={css}>{this.props.children}</button>
    );
  }
}
export const LoginButton = class LoginButton extends Component{
  render(){
    return(
      <Button proc={this.props.proc} size={this.props.size}>Sign In</Button>
    )
  }
}
export const Button=类按钮扩展组件{
render(){
var css=“w3 btn w3应用程序按钮w3 round”;
css+=(this.props.size)?“w3-”+this.props.size:”;
返回(
{this.props.children}
    );
  }
}
export const LoginButton=类LoginButton扩展组件{
render(){
返回(
登录
)
}
}

我现在需要的是能够点击登录按钮,它会调用一个函数来进行一些后端通信。我需要能够访问TextField状态,以便从该函数操作
errorflag
errormsg
。显然,我的方法是不正确的;然而,我发现很难找到一个可以效仿的例子。任何帮助都将不胜感激。

在这种情况下,将函数回调作为prop(在本例中称为
proc
)传递是正确的调用

但是,当从下面的按钮调用您的
loginUser
时,类的上下文将不会绑定到函数上下文,从而使您无法使用组件的状态

您可以通过在函数上调用
.bind(this)
或将其设置为箭头函数来解决此问题:

  loginUser = ev => {
    //Call your backend here
    this.setState({ //No more undefined errors
      errorflage: true,
      errormsg: "This is a required Field"
    })
  }
我还建议将按钮组件更改为无状态组件,因为它们不需要管理状态:

export function Button(props) {
    var css= "w3-btn w3-app-button w3-round";
    css += (this.props.size) ? " w3-"+this.props.size : "";
    return (
      <button onClick={props.proc} className={css}>{props.children}</button>
    );
}

export function LoginButton({ proc, size }) {
    return(
      <Button proc={proc} size={size}>Sign In</Button>
    )
}
导出功能按钮(道具){
var css=“w3 btn w3应用程序按钮w3 round”;
css+=(this.props.size)?“w3-”+this.props.size:”;
返回(
{props.children}
);
}
导出函数LoginButton({proc,size}){
返回(
登录
)
}
简短版本:

const LoginButton = ({ proc, size }) => <Button proc={proc} size={size}>Sign In</Button>
export LoginButton
constloginbutton=({proc,size})=>登录
导出登录按钮

在这种情况下,将函数回调作为prop(在本例中称为
proc
)传递是正确的调用

但是,当从下面的按钮调用您的
loginUser
时,类的上下文将不会绑定到函数上下文,从而使您无法使用组件的状态

您可以通过在函数上调用
.bind(this)
或将其设置为箭头函数来解决此问题:

  loginUser = ev => {
    //Call your backend here
    this.setState({ //No more undefined errors
      errorflage: true,
      errormsg: "This is a required Field"
    })
  }
我还建议将按钮组件更改为无状态组件,因为它们不需要管理状态:

export function Button(props) {
    var css= "w3-btn w3-app-button w3-round";
    css += (this.props.size) ? " w3-"+this.props.size : "";
    return (
      <button onClick={props.proc} className={css}>{props.children}</button>
    );
}

export function LoginButton({ proc, size }) {
    return(
      <Button proc={proc} size={size}>Sign In</Button>
    )
}
导出功能按钮(道具){
var css=“w3 btn w3 app button w3 round”;
css+=(this.props.size)?“w3-”+this.props.size:”;
返回(
{props.children}
);
}
导出函数LoginButton({proc,size}){
返回(
登录
)
}
简短版本:

const LoginButton = ({ proc, size }) => <Button proc={proc} size={size}>Sign In</Button>
export LoginButton
constloginbutton=({proc,size})=>登录
导出登录按钮

那么您是否需要按钮才能访问处于文本字段状态的内容?另外,作为提示,您可以直接导出类,而不需要生成常量。所以你可以说“export class LoginButton Extendes Component”可能是重复的,那么你需要按钮才能访问TextField状态中的内容吗?另外,作为提示,您可以直接导出类,而不需要生成常量。因此,您可以说“export class LoginButton Extendes Component”除了使按钮成为无状态之外,my
loginUser
函数是绑定的;但是,它仍然没有将状态设置为this.state在函数中为null。是什么让你说它是绑定的?您在函数中的哪个位置使用
this.state
?它在TextField组件中。除了将按钮设置为无状态外,my
loginUser
函数是绑定的;但是,它仍然没有将状态设置为this.state在函数中为null。是什么让你说它是绑定的?您在函数中的哪个位置使用此.state?它在TextField组件中。