当前位置: 首页 > 知识库问答 >
问题:

点击按钮未触发React中的“handleSubmit”功能

贝镜
2023-03-14

我正在构建一个反应轨道应用程序。我在页面上有一个按钮,用户可以指示他们是否要加入会议。单击“join”按钮应在当前用户和事件之间创建一个rsvp关系,该按钮将切换到“Leave”,如果用户随后单击“Leave(离开)”按钮,该关系将从rails后端删除。在搞乱我的react组件后,我的“Join”按钮没有触发“onSubmit”功能,“Leave”按钮似乎返回了一个错误消息“submission form cancelled because form is not connected”。如果有人能帮我理清逻辑,我将不胜感激。

import React from 'react'

class EventsIndexContainer extends React.Component {
 constructor(props) {
 super(props)
 this.state = {
  active: props.rsvp
 }
 this.toggleButton = this.toggleButton.bind(this)
 this.handleRsvpSubmit = this.handleRsvpSubmit.bind(this)
 this.handleRsvpDelete = this.handleRsvpDelete.bind(this)
}

toggleButton() {
 this.setState({active: !this.state.active})
}

handleRsvpSubmit(event) {
 event.preventDefault()
 let formPayLoad = {
  user_id: this.props.current_user.id,
  event_id: this.props.selectedId
 }
 this.props.addRsvp(formPayLoad)
}

handleRsvpDelete() {
 fetch(`/api/v1/rsvps/${this.props.selectedId}`, {
  method: 'DELETE'}
 )
}

render() {
 let button
 let joinButton =
 <form onSubmit={this.handleRsvpSubmit}>
  <button type="button" onClick={() => (this.props.handleSelect(), 
  this.toggleButton())}>Join</button>
 </form>

 let leaveButton =
  <button type="button" onClick={() => (this.toggleButton(), 
  this.handleRsvpDelete)}>Leave</button>

 button = this.state.active? leaveButton : joinButton

 return(
   <div>
      <h4>{this.props.location} - {this.props.meal_type} at 
      {this.props.time}</h4>
      <p>{this.props.group.name}</p>
      {button}
      <button>See who is going</button>
  </div>
 )
}
}

export default EventsIndexContainer

这是父容器:

import React from 'react'
import GroupIndexContainer from './GroupIndexContainer'
import EventsIndexContainer from './EventsIndexContainer'

class MainContainer extends React.Component {
 constructor(props) {
 super(props)
 this.state = {
  groups: [],
  current_user: null,
  events: [],
  rsvps: [],
  selectedId: null
 }
 this.fetchGroups = this.fetchGroups.bind(this)
 this.fetchEvents = this.fetchEvents.bind(this)
 this.handleSelect = this.handleSelect.bind(this)
 this.addRsvp = this.addRsvp.bind(this)
 this.fetchRsvps = this.fetchRsvps.bind(this)
 }

 componentDidMount() {
    fetch('api/v1/users.json', {
      credentials: 'same-origin',
      method: "GET",
      headers: { 'Content-Type': 'application/json' }
    })
    .then(response => response.json())
    .then(data => {
      this.setState ({current_user: data.user})
    })
    .then(this.fetchGroups())
    .then(this.fetchEvents())
    .then(this.fetchRsvps())
  }

  fetchGroups() {
    fetch('/api/v1/groups', {
      credentials: 'same-origin',
      method: "GET",
      headers: { 'Content-Type': 'application/json' }
    })
    .then(response => response.json())
    .then(data => {
      this.setState({groups: data.groups})
    })
  }

  fetchEvents() {
    fetch('/api/v1/events', {
      credentials: 'same-origin',
      method: "GET",
      headers: { 'Content-Type': 'application/json' }
    })
    .then(response => response.json())
    .then(data => {
      this.setState({events: data})
    })
  }

  fetchRsvps() {
    fetch('/api/v1/rsvps', {
      credentials: 'same-origin',
      method: "GET",
      headers: { 'Content-Type': 'application/json' }
    })
    .then(response => response.json())
    .then(data => {
      this.setState({rsvps: data.rsvps})
    })
  }

  handleSelect(id) {
    this.setState({selectedId: id})
  }

  addRsvp(formPayLoad) {
    fetch('/api/v1/rsvps', {
      method: 'POST',
      credentials: 'same-origin',
      headers: { 'Accept': 'application/json', 'Content-Type': 'application/json'},
      body: JSON.stringify(formPayLoad)
    })
  }

  render() {
    let groups = this.state.groups.map((group) => {
      return (
        <GroupIndexContainer
          key={group.id}
          id={group.id}
          name={group.name}
        />
      )
    })

    let rsvp_ids = this.state.rsvps.map(rsvp => rsvp.event_id)
    let events = this.state.events.map((event) => {
      return(
        <EventsIndexContainer
          key={event.id}
          id={event.id}
          rsvp={rsvp_ids.some(rsvp_id => rsvp_id == event.id) ? true : false}
          location={event.location}
          meal_type={event.meal_type}
          time={event.time}
          group={event.group}
          current_user={this.state.current_user}
          user={event.user}
          selectedId={this.state.selectedId}
          addRsvp={this.addRsvp}
          handleSelect={() => this.handleSelect(event.id)}
        />
      )
    })

    return(
      <div className="wrapper">

        <div className="groups-index">
          <h3>Your Groups:</h3>
          {groups}
        </div>

        <div className="events-index">
          <h3>What's happening today...</h3>
          {events}
        </div>

      </div>
    )
  }
}

       export default MainContainer

共有1个答案

上官鸿晖
2023-03-14

在返回之前构建的按钮渲染函数中是一个表单或一个按钮。我建议简单地检查组件的状态,避免使用表单(它没有插入到DOM中,因此“提交表单被取消,因为表单没有连接”消息)。

基本上,如果您使用按钮onClick功能,您的代码会简单得多。您不必处理按钮类型提交按钮,这将触发onSubmit用于前者或不用于后者,如:之间的区别

此外,在组件属性中使用箭头函数不是一个好的做法,这里有详细的记录:为什么JSX道具不应该使用箭头函数或绑定?

因此,我再次建议您将onClick属性更改为类似onClick={this.handleLeave},并在那里处理工作(对0.05 handleJoin也这样做)。

我试图在下面的代码片段中对您的代码进行一点修改,希望这会有所帮助!

class EventsIndexContainer extends React.Component {
  constructor(props) {
    super(props)
    this.state = {
      active: props.rsvp
    }
    this.toggleButton = this.toggleButton.bind(this)
    this.handleRsvpSubmit = this.handleRsvpSubmit.bind(this)
    this.handleRsvpDelete = this.handleRsvpDelete.bind(this)
    
    // Stub
    this.handleSelect = this.handleSelect.bind(this)
  }
  
  handleSelect() {
    console.log("handleSelect called");
  }
  
  toggleButton() {
    this.setState({active: !this.state.active})
  }
  
  // event argument removed here, wasn't used anyway
  handleRsvpSubmit() {
    console.log("handleRsvpSubmit called")
  }
  
  handleRsvpDelete() {
    console.log("handleRsvpDelete called")
  }
  
  render() {
    return(
      <div>
        <h4>Hello</h4>
        <p>Group name</p>
        { this.state.active ?
          <button type="button" onClick={() => (this.toggleButton(), this.handleRsvpDelete())}>Leave</button>
        :
          <button type="button" onClick={() =>(this.handleSelect(),this.toggleButton(), this.handleRsvpSubmit())}>Join</button>
        }
        <button>See who is going</button>
      </div>
      )
    }
  }
  
ReactDOM.render(
  <EventsIndexContainer rsvp={ false } />,
  document.getElementById('container')
);
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.min.js"></script>
<div id="container">
    <!-- This element's contents will be replaced with your component. -->
</div>

 类似资料:
  • 问题内容: 似乎是一个简单的问题,但解决其他问题的方法似乎对我没有用。 试图通过单击按钮来触发AJAX请求,但似乎并未触发。 HTML示例 javascript 问题答案: 您拥有的代码在拨弄中工作得很好。初始页面加载后,按钮是否通过AJAX动态呈现? 用 代替

  • > 按常规声明代码 Page language=“vb”autoeventwireup=“false”masterpageFile=“~/site.master”codeBehind=“RetailCompetition.aspx.vb”inherits=“company.applications.production.ui.RetailCompetition” 事件

  • PayPal Checkout按钮点击本身打开PayPal安全窗口,其余工作正常。当客户点击第一个单选按钮时,我想再次打开PayPal安全窗口,即触发点击PayPal结账按钮。如果按钮本身出现在iframe中,而我无法触发该按钮跨域的单击事件,我该怎么做?有没有办法触发签出按钮的点击? 这里是超文本标记语言代码: 和Javascript代码: 编辑:作为一个工作的例子,我会建议这个网站,但这是有点

  • 我找到了其他相关的问题,但没有一个答案实际上解决了我的问题。这个按钮在IE上很好用,但在Chrome上不行。我尝试移除span元素,将按钮放在任何其他标记之外,但仍然触发了两次。这个temple扩展了一个'base.html'文件,代码位于'main'元素中。 HTML: jQuery:

  • 当按钮单击时,是否有任何机制显式地触发按键事件。当我单击java UI中命名为“+”的按钮时,它将显式地触发“+”键按下事件。

  • 所以我试图让我的应用程序发送短信自动给给定的号码时,用户按下按钮。 我可以让它打开messenger并编写文本,但我不能让它自动发送。 我的代码如下(我想最重要的部分); 那么,我怎样才能让它发送短信呢? 顺便说一句,我添加了权限:“Android。权限。发送短信”