onClick事件后React组件未更新

时间:2019-01-16 03:10:42

标签: javascript reactjs typescript ecmascript-6

我有一个功能齐全的react-typescript组件,该组件接收正确触发的点击处理程序,但是该组件在click event之后不会更新。

即:

// for reasons out of the scope of this question, 
// this component should be functional

const Heroes: React.SFC<{}> = () => {
  // for fututre reasons, these variables must leave within this component
  const thor = "isHero";
  const hulk = "isHero";

  function appendSpan() {
    console.log(thor === hulk);
    return thor === hulk ? <span>yes</span> : <span>no</span>;
  }

  return <p onClick={appendSpan}>Are they both heroes?</p>;
};

function App() {
  return (
    <div className="App">
      <Heroes />
    </div>
  );
}

如果我立即调用该方法,即<p>Are they both heroes? {appendSpan()}</p>

<span>被相应地附加,但是,对于onClick场景,情况并非如此。

您能帮我理解我在这里想念的东西吗?

这里是code sandbox

3 个答案:

答案 0 :(得分:2)

您可以将Heroes组件更改为有状态组件,并在单击时更新状态或使用Hooks

更新用于tsx

class Heroes extends React.Component <{}, any> {
    // for fututre reasons, these variables must leave within this component
    private thor = "isHero";
    private hulk = "isHero";

    constructor(props) {
      super(props);
      this.state = {
        showButton: false
      };
    }

    appendSpan() {
      // update the state to show the button
      this.setState({
        showButton: true
      });
    }

    render() {
      const { showButton } = this.state;
      let button = this.thor === this.hulk ? <span> yes </span> : <span>no</span > ;
      return ( <p onClick={() => this.appendSpan()}> Are they both heroes ? 
        { showButton ? button : '' } 
        </p>);
      }
}

function App() {
  return ( <div className = "App" >
      <Heroes/>
    </div>
  );
}

另一个带有React Hooks的更新,已在React v16.8.0-alpha.0

中引入

// import useState hooks
import { useState } from 'react';

const Heroes: React.SFC<any> = () => {
  // for fututre reasons, these variables must leave within this component
  const thor = "isHero";
  const hulk = "isHero";
  
  // declare a new state variable flag and the update function setFlag
  const [flag, setFlag] = useState(false);
  
  let button = thor === hulk ? <span> yes </span> : <span> no </span >;

  return (<p onClick={() => setFlag(true)}>Are they both heroes?
    {flag ? button : ''}
  </p>);
};

function App() {
  return (
    <div className="App">
      <Heroes />
    </div>
  );
}

创建了一个沙盒here,用于通过react挂钩实现。

答案 1 :(得分:0)

因为您的.appendSpan()返回了响应dom,但它返回的是onClick事件的范围。

您说<p>Are they both heroes? {appendSpan()}</p>时,实际上是在告诉应用程序在<p>标签内附加跨度...

但是onClick={appendSpan},您告诉它在哪里追加?您没有告诉要追加的地方。因此它永远不会被添加到DOM树中

答案 2 :(得分:0)

appendSpan函数的返回结果必须是您在render函数中返回的结果的一部分。

您可以将状态保留在应用程序组件上,并编写一个onClick函数来更改状态。将onClick和状态作为道具传递给Heroes组件。根据您从道具收到的状态,决定要渲染什么。

React不会从类变量中“反应”,我看到您想将状态保留在类中。尝试寻找钩子

Edit 01r3yy2n5v