从子组件更新父状态在 reactjs 中不起作用

Posted

技术标签:

【中文标题】从子组件更新父状态在 reactjs 中不起作用【英文标题】:Updating parent state from child components not working in reactjs 【发布时间】:2020-08-02 08:53:53 【问题描述】:

当我遇到一个通过子组件回调更新父组件的示例时,我正在经历 react official documentation。我能够理解流程是如何工作的。但是,当我尝试进一步优化代码时,它无法通过回调更新组件。

原始代码:

https://codepen.io/gaearon/pen/QKzAgB?editors=0010

我的代码更改:

    class LoginControl extends React.Component 
  constructor(props) 
    super(props);
    this.handleLoginClick = this.handleLoginClick.bind(this);
    this.handleLogoutClick = this.handleLogoutClick.bind(this);
    this.state = isLoggedIn: false;
    this.button = <MyButton message="Login" onClick=this.handleLoginClick />;
  

  handleLoginClick() 
    this.setState(isLoggedIn: true);
  

  handleLogoutClick() 
    this.setState(isLoggedIn: false);
  

  render() 
    const isLoggedIn = this.state.isLoggedIn;
    if (isLoggedIn) 
      this.button = <MyButton message="Logout" onClick=this.handleLogoutClick />;
     else 
      this.button = <MyButton message="Login" onClick=this.handleLoginClick />;
    

    return (
      <div>
        <Greeting isLoggedIn=isLoggedIn />
        this.button
      </div>
    );
  


function UserGreeting(props) 
  return <h1>Welcome back!</h1>;


function GuestGreeting(props) 
  return <h1>Please sign up.</h1>;


function Greeting(props) 
  const isLoggedIn = props.isLoggedIn;
  if (isLoggedIn) 
    return <UserGreeting />;
  
  return <GuestGreeting />;


class MyButton extends React.Component 
  constructor(props) 
    super(props);
    this.message=props.message;
    this.click=props.onClick;
  
  render() 
    return (
    <button onClick=this.click> 
        this.message
    </button>  
    );
  


ReactDOM.render(
  <LoginControl />,
  document.getElementById('root')
);

【问题讨论】:

codepen 链接似乎对我有用。你看到了什么错误? 代码正在运行...请包括您在问题中遇到的错误。 codeopen 链接正常工作。如果您剪切粘贴我的代码,然后尝试单击显示的按钮,它将不起作用。 【参考方案1】:

好的,这里的主要问题是您试图将许多东西分配给“this”。 当组件的方法或属性发生更改时,React 不会跟踪更改并重新渲染。 尽量避免这种模式,直接使用 state 和 props。 只有状态或道具的更改才会导致组件重新渲染。 在您的情况下,您可以查看以下代码:

   class LoginControl extends React.Component 


     state = isLoggedIn : false

  handleLoginClick = () => 
    this.setState(isLoggedIn: true);
  

  handleLogoutClick = () => 
    this.setState(isLoggedIn: false);
  

  button = () => 

    const message = this.state.isLoggedIn ? "Logout" : "Login";
    const onClick = this.state.isLoggedIn ? this.handleLogoutClick : this.handleLoginClick;
    return <MyButton message=message onClick=onClick />
  

  render() 


    return (
      <div>
        <Greeting isLoggedIn=this.state.isLoggedIn />
       this.button()
      </div>
    );
  


function UserGreeting(props) 
  return <h1>Welcome back!</h1>;


function GuestGreeting(props) 
  return <h1>Please sign up.</h1>;


function Greeting(props) 
  const isLoggedIn = props.isLoggedIn;
  if (isLoggedIn) 
    return <UserGreeting />;
  
  return <GuestGreeting />;


class MyButton extends React.Component 
  constructor(props) 
    super(props);
    this.message=props.message;
    this.click=props.onClick;
  
  render() 
    return (
    <button onClick=this.props.onClick> 
        this.props.message
    </button>  
    );
  


ReactDOM.render(
  <LoginControl />,
  document.getElementById('root')
);

【讨论】:

谢谢汤姆。这样可行。但是,我不明白为什么原始代码会失败。我尝试通过代码路径随处添加console.log 语句以及我的更改。似乎 LoginControl.render 通过更改正确调用。在这种情况下,不应该更新按钮变量吗,因为我们在 LoginControl.render 中重新为其分配了一个新值? 也许这会让它更清楚一点。如果您将渲染函数更改为 render() const isLoggedIn = this.state.isLoggedIn; 您可以按原样使用您的代码让按钮; if (isLoggedIn) button = () => ; else button = () => ; return ( button() );

以上是关于从子组件更新父状态在 reactjs 中不起作用的主要内容,如果未能解决你的问题,请参考以下文章

当孩子必须更新父母的状态时,this.setState 不起作用

Angular 4 - 从子组件调用父方法不起作用

如何在 Reactjs 中将数据从子组件传递到父组件? [复制]

从子组件到父组件的绑定字符串字段不起作用

如何在 ReactJS 中将更改的状态从子组件传递给其父组件

引导类在 ReactJS 组件中不起作用