【问题标题】:React JS, using parameters in onClick to change state?React JS,使用onClick中的参数来改变状态?
【发布时间】:2023-03-29 17:22:01
【问题描述】:

我需要在单击时设置参数以根据某人单击的按钮发送字符串。我意识到要设置参数,我需要在 render () {} 中创建一个函数,但现在当我尝试使用 this.setState({zone: location}) 时,出现以下错误:

TypeError: Cannot read property 'setState' of undefined

这是我的代码:

import React, { Component } from "react";
import "./styles/homeStyle.css";
import timerIcon from "./styles/media/timer_clock.png";
import streaksIcon from "./styles/media/streaks_fire.png";
import guideIcon from "./styles/media/guide_meditation.png";

class Main extends Component {
    state = {
        zone: "home",
    };
    render() {
        return (
            <React.Fragment>
                <div id="diagonal_shape"></div>
                <div className="row">
                    <div className="col s12" id="title">
                        <h4 className="center-align">
                            Peaceful<span id="title_steps"> Steps</span>
                            <br />
                            {this.state.zone}
                        </h4>
                    </div>
                    <div id="nav_bar">
                        <div className="col s4" id="goto_timer">
                            <p className="center-align">
                                <img src={timerIcon} width="60%" alt="clock" onClick={() => goTo("timer")} />
                                <br />
                                Timer
                            </p>
                        </div>
                        <div className="col s4">
                            <p className="center-align">
                                <img src={streaksIcon} width="60%" alt="fire" onClick={() => goTo("stats")} />
                                <br />
                                Stats
                            </p>
                        </div>
                        <div className="col s4">
                            <p className="center-align">
                                <img src={guideIcon} width="60%" alt="meditating" onClick={() => goTo("guides")} />
                                <br />
                                Guides
                            </p>
                        </div>
                    </div>
                </div>
            </React.Fragment>
        );
        function goTo(location) {
            console.log("yes " + location);
            this.setState({ zone: location });
        }
    }
}

export default Main;

我很确定这是因为我不能在渲染函数中使用 this.setState({}),但我不知道如何让它工作。

【问题讨论】:

    标签: javascript reactjs scope onclick setstate


    【解决方案1】:

    您收到错误的原因是因为您在返回后定义了一个function inside render 方法。

    请注意此处的功能一词(不是箭头乐趣)。当您定义一个函数时,js 引擎会将其提升到其范围的顶部,值为 undefined。这就是你得到错误的原因。

    从技术上讲,您可以在渲染方法中定义处理程序,但您必须确保使用箭头函数并在渲染方法返回语句之前定义它。 See demo here

    但是,最好不要在渲染方法中定义处理程序。

    render 中编写处理程序的代码 sn-p

    export class App extends Component {
      state = {
        name: "hello"
      };
    
      render() {
        console.log("state", this.state.name);
        const clickMe = () => {
          console.log(this.setState({ name: "hi!!!!" }));
        };
        return (
          <div className="App">
            <h1>Hello CodeSandbox</h1>
            <h2>Start editing to see some magic happen!</h2>
            <button onClick={() => clickMe()}>Click Me</button>
          </div>
        );
      }
    }
    export default App;
    

    【讨论】:

      【解决方案2】:

      如果您在函数中执行state 更新,那么您不能在类方法中定义函数。将goTo 方法定义为class 方法,然后在单击按钮时像this.goto("some string") 一样调用它。

      你需要bind thisgoTo 方法或者只使用arrow function

      class Main extends Component {
      
          constructor(props) {
              super(props)
              this.state = {
                  zone: "home",
              };
              this.goTo = this.goTo.bind(this);
          }
      
          goTo(location) {
              console.log("yes " + location);
              this.setState({ zone: location });
          }
      
          render() {
              return (
                  <React.Fragment>
                      <div id="diagonal_shape"></div>
                      <div className="row">
                          <div className="col s12" id="title">
                              <h4 className="center-align">
                                  Peaceful<span id="title_steps"> Steps</span>
                                  <br />
                                  {this.state.zone}
                              </h4>
                          </div>
                          <div id="nav_bar">
                              <div className="col s4" id="goto_timer">
                                  <p className="center-align">
                                      <img src={timerIcon} width="60%" alt="clock" onClick={() => this.goTo("timer")} />
                                      <br />
                                      Timer
                                  </p>
                              </div>
                              <div className="col s4">
                                  <p className="center-align">
                                      <img src={streaksIcon} width="60%" alt="fire" onClick={() => this.goTo("stats")} />
                                      <br />
                                      Stats
                                  </p>
                              </div>
                              <div className="col s4">
                                  <p className="center-align">
                                      <img src={guideIcon} width="60%" alt="meditating" onClick={() => this.goTo("guides")} />
                                      <br />
                                      Guides
                                  </p>
                              </div>
                          </div>
                      </div>
                  </React.Fragment>
              );
          }
      }
      export default Main;
      

      如果你想在class 方法中使用函数并想访问fields/methods 类,那么将class this 变量绑定到函数或只使用arrow 函数。这样function 中的this 变量将引用class

      class Main extends Component {
          state = {
              zone: "home",
          };
      
      
          render() {
      
              function goTo(location) {
                  console.log("yes " + location);
                  this.setState({ zone: location });
              }
              goTo = goTo.bind(this);
      
              return (
                  <React.Fragment>
                      <div id="diagonal_shape"></div>
                      <div className="row">
                          <div className="col s12" id="title">
                              <h4 className="center-align">
                                  Peaceful<span id="title_steps"> Steps</span>
                                  <br />
                                  {this.state.zone}
                              </h4>
                          </div>
                          <div id="nav_bar">
                              <div className="col s4" id="goto_timer">
                                  <p className="center-align">
                                      <img src={timerIcon} width="60%" alt="clock" onClick={() => this.goTo("timer")} />
                                      <br />
                                      Timer
                                  </p>
                              </div>
                              <div className="col s4">
                                  <p className="center-align">
                                      <img src={streaksIcon} width="60%" alt="fire" onClick={() => this.goTo("stats")} />
                                      <br />
                                      Stats
                                  </p>
                              </div>
                              <div className="col s4">
                                  <p className="center-align">
                                      <img src={guideIcon} width="60%" alt="meditating" onClick={() => this.goTo("guides")} />
                                      <br />
                                      Guides
                                  </p>
                              </div>
                          </div>
                      </div>
                  </React.Fragment>
              );
      
      
          }
      }
      export default Main;
      

      我会建议第一种方法,因为它更清晰易读。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2021-08-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多