我正在尝试调用 switch_func 函数。但不知何故无法获得预期的结果

I am trying to call the switch_func function. But somehow not able to get the desired result

<!DOCTYPE html>
<html>
<script src="https://unpkg.com/react@16/umd/react.production.min.js"></script>
<script src="https://unpkg.com/react-dom@16/umd/react-dom.production.min.js"></script>
<script src="https://unpkg.com/babel-standalone@6.15.0/babel.min.js"></script>
<body>
  
<div id="root"></div>

<script type="text/babel">
class Hello extends React.Component {
  constructor(props) {
        super(props);
        this.state = { myStr: "Initial state" };
        this.switch_func = this.switch_func.bind(this);
    }
    
    switch_func = () => {
  // the setState if commented ...the initial state of myStr is executed ..meaning the function is called however the setState method doesnt work . Can anyone tell why this is happening?
  
     this.setState({ myStr: "yess"});
      return (
            <div>
                <h3>{this.state.myStr}</h3>
            </div>
        );
    }
    

    render() {
        return (
            <div>
                <h1>Hello, world!</h1>
    {this.switch_func()}
            </div>
        );
    }
}

ReactDOM.render(<Hello />, document.getElementById('root'))
</script>

</body>
</html>

即使在绑定函数switch_func之后,它也不会被执行并且myStr 的状态保持与初始化时相同。请帮助解决编码未能显示所需结果的地方。

谁能告诉我为什么 setState 方法在这里不起作用?

期望的输出是 myStr 的状态更改为 - "Yes its four!"

class MyClass extends React.Component {
    constructor(props) {
        super(props);
        this.state = {myStr: "Initial state"};
        this.switch_func = this.switch_func.bind(this);
    }
    switch_func = ()=> {
        this.setState({myStr: "In function"});
        switch (1 + 3) {
            case 2 + 2:
                this.setState({ myStr: "Yes its four!"});
                break;
            default:
                this.setState({ myStr: "Oops! default"});
        }

    return(
        <div>
            <h3>{this.state.myStr}</h3>
        </div>
    );
  }

    render(){
        return (
            <div>
            <h1>Hello, world!</h1>
            {this.switch_func()}
        </div>
        );
    }
}

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


您只需在末尾添加括号即可调用该函数。这将导致无限循环,但每次您的组件渲染时,它都会更新状态,进而导致重新渲染等。

class MyClass extends React.Component {
    constructor(props) {
        super(props);
        this.state = { myStr: "Initial state" };
        this.switch_func = this.switch_func.bind(this);
    }
    switch_func = () => {
        switch (1 + 3) {
            case 2 + 2:
                this.setState({ myStr: "Yes its four!" });
                break;
            default:
                this.setState({ myStr: "Oops! default" });
        }

        return (
            <div>
                <h3>{this.state.myStr}</h3>
            </div>
        );
    }

    render() {
        return (
            <div>
                <h1>Hello, world!</h1>
                {this.switch_func()}
            </div>
        );
    }
}

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

你不应该在 render 中调用 switch 函数,因为它可能会导致你的组件陷入无限循环 - 每次渲染时,状态都会改变,所以......它会再次渲染。

此外,在一个函数中混合渲染和状态更新是非常危险的 - 永远不要这样做,因为它可能会导致大量优化泄漏。

将您的函数调用移至另一个方法,例如componentDidMount():

class MyClass extends React.Component {
    constructor(props) {
        super(props);
        this.state = {myStr: "Initial state"};
    }

    componentDidMount() {
      switchFunc();
    }

    switchFunc = () => {
        switch (1 + 3) {
            case 2 + 2:
                this.setState({ myStr: "Yes its four!"});
                break;
            default:
                this.setState({ myStr: "Oops! default"});
        }
    }

    render(){
        return (
            <div>
                <h1>Hello, world!</h1>
                <div>
                    <h3>{this.state.myStr}</h3>
                </div>
            </div>
        );
    }
}

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

componentDidMount 是 React 提供的一种特殊方法(如 render),它允许在安装组件时控制组件行为。更多关于该方法的信息:https://reactjs.org/docs/state-and-lifecycle.html

此外,请注意,暂时将渲染 myStr 与 render 方法分开是一种矫枉过正 - 只需像我的示例一样直接在 render 方法中使用它。

附带说明 - 尝试为您的方法使用 camelCased 名称,以使其与其余代码保持一致(如我更新的示例中所示)。

另一个关于绑定的优化信息 - 你添加了 .bind() 调用你的构造函数 - 它不是必需的,因为你的 switchFunc 没有在 class 之外的任何上下文中使用(因此,它的 this 总是指向 class,所以你不需要再次 .bind() 上下文)。此外,更重要的是 - 你将它写成一个 lambda (() => {}) 函数,而不是一个普通函数 - lambda 没有它们的上下文并从它们定义的地方继承父上下文 - 因此它将 总是指向 class this 没有任何显式绑定的上下文