react 点击两次_为什么我的函数在React中被两次调用?

本文探讨了在React组件中,一个onClick事件处理函数被意外调用两次的问题。作者发现此问题可能与单选按钮的样式设计有关。代码示例展示了如何在事件处理函数中设置console.log来追踪函数调用,并提供了组件的完整实现,包括改变运输选项的逻辑。问题的根源在于同时使用了onClick和onChange事件,导致函数被重复调用。
摘要由CSDN通过智能技术生成

我有一个想法,可能是因为我正在做一些样式设计来更改单选按钮,但是我不确定。我正在设置一个onClick事件,该事件两次调用了我的函数。我已删除它以确保它没有在其他地方被触发,并且onClick似乎是罪魁祸首。

className="CheckboxContainer"

onClick={() =>

this.changeShipping({ [k]: i })

}

>

{shipOption.carrier

? shipOption.carrier.serviceType

: null}{' '}

{shipOption.name}

${shipOption.amount}

type="radio"

value={i}

className="ShippingInput"

onChange={() =>

this.setState({

shippingOption: {

...this.state.shippingOption,

[k]: i

}

})

}

checked={

this.state.shippingOption[k] === i

? true

: false

}

/>

我的功能目前仅是运输选项的简单控制台日志:

changeShipping(shipOption){

console.log('clicked') // happening twice

}

如果没有任何理由可以在这里看到为什么会发生这种情况,我可以发布其余代码,但是有很多方面,我认为这与之无关,但是我认为这是一个很好的起点。

完整代码:

import React, { Component } from 'react'

import fetch from 'isomorphic-fetch'

import { Subscribe } from 'statable'

import { FoldingCube } from 'better-react-spinkit'

import styles from './styles'

import { cost, cartState, userInfo, itemState, Api } from '../../state'

import { removeCookies, resetCart } from '../../../injectState'

export default class ShippingOptions extends Component {

constructor(props) {

super(props)

this.state = {

shippingOption: {}

}

this.changeShipping = this.changeShipping.bind(this)

}

async changeShipping(shipOption) {

const shipKey = Object.keys(shipOption)[0]

// if (userInfo.state.preOrderInfo.setShip[shipKey] === shipOption[shipKey]) {

// return

// }

let updatedShipOption = {}

Object.keys(shipOption).forEach(k => {

updatedShipOption = userInfo.state.preOrderInfo.setShip

? { ...userInfo.state.preOrderInfo.setShip, [k]: shipOption[k] }

: shipOption

})

userInfo.setState({

preOrderInfo: {

...userInfo.state.preOrderInfo,

setShip: updatedShipOption

}

})

// Make request to change shipping option

const { preOrderInfo } = userInfo.state

const shippingRes = await fetch(Api.state.api, {

body: JSON.stringify(preOrderInfo),

method: 'POST'

})

.then(res => res.json())

.catch(err => {

let error = ''

if (

err.request &&

(err.request.status === 404 || err.request.status === 502)

) {

error = `Error with API: ${err.response.statusText}`

} else if (err.request && err.request.status === 0 && !err.response) {

error =

'Something went wrong with the request, no response was given.'

} else {

error = err.response || JSON.stringify(err) || err

}

cartState.setState({

apiErrors: [error],

loading: false

})

})

console.log(shippingRes)

}

async componentDidMount() {

if (cartState.state.tab === 2) {

const { shipping } = userInfo.state

const { items, coupon } = itemState.state

let updated = { ...shipping }

const names = updated.shippingFullName.split(' ')

updated.shippingFirst = names[0]

updated.shippingLast = names[1]

delete updated.shippingFullName

updated.site = cartState.state.site

updated.products = items

updated.couponCode = coupon

updated.addressSame = userInfo.state.addressSame

cartState.setState({

loading: true

})

const shippingRes = await fetch(Api.state.api, {

body: JSON.stringify(updated),

method: 'POST'

})

.then(res => res.json())

.catch(err => {

let error = ''

if (

err.request &&

(err.request.status === 404 || err.request.status === 502)

) {

error = `Error with API: ${err.response.statusText}`

} else if (err.request && err.request.status === 0 && !err.response) {

error =

'Something went wrong with the request, no response was given.'

} else {

error = err.response || JSON.stringify(err) || err

}

cartState.setState({

apiErrors: [error],

loading: false

})

})

console.log(shippingRes)

return

shippingRes.products.forEach(product => {

const regexp = new RegExp(product.id, 'gi')

const updatedItem = items.find(({ id }) => regexp.test(id))

if (!updatedItem) {

console.warn('Item not found and being removed from the array')

const index = itemState.state.items.indexOf(updatedItem)

const updated = [...itemState.state.items]

updated.splice(index, 1)

itemState.setState({

items: updated

})

return

}

updatedItem.price = product.price

itemState.setState({

items: itemState.state.items.map(

item => (item.id === product.id ? updatedItem : item)

)

})

})

updated.shippingOptions = shippingRes.shippingOptions

Object.keys(updated.shippingOptions).forEach(k => {

this.setState({

shippingOption: { ...this.state.shippingOption, [k]: 0 }

})

updated.setShip = updated.setShip

? { ...updated.setShip, [k]: 0 }

: { [k]: 0 }

})

updated.success = shippingRes.success

updated.cartId = shippingRes.cartId

updated.locations = shippingRes.locations

userInfo.setState({

preOrderInfo: updated

})

cost.setState({

tax: shippingRes.tax,

shipping: shippingRes.shipping,

shippingOptions:

Object.keys(updated.shippingOptions).length > 0

? updated.shippingOptions

: null

})

cartState.setState({

loading: false,

apiErrors: shippingRes.errors.length > 0 ? shippingRes.errors : null

})

if (shippingRes.errors.length > 0) {

removeCookies()

shippingRes.errors.forEach(err => {

if (err.includes('CRT-1-00013')) {

itemState.setState({ coupon: '' })

}

})

}

}

}

render() {

return (

{(cart, cost, itemState) => {

if (cart.loading) {

return (

)

}

if (cart.apiErrors) {

return (

Please Contact Customer Support

(contact information for customer support)

{cart.apiErrors.map((error, i) => {

return (

{error}

)

})}

)

}

return (

{cost.shippingOptions ? (

{Object.keys(cost.shippingOptions).map((k, i) => {

const shipOptions = cost.shippingOptions[k]

const updatedProducts =

shipOptions.products.length === 0

? []

: shipOptions.products.map(product =>

itemState.items.find(

item => item.id === product.id

)

)

return (

{shipOptions.options.map((shipOption, i) => {

return (

4. {shipOption.name} Shipping Options

{updatedProducts.length > 0 ? (

{updatedProducts.map((product, i) => (

for{' '}

{shipOption.name === 'Freight'

? 'Large'

: 'Small'}{' '}

{product.name} from{' '}

{k.charAt(0).toUpperCase() + k.slice(1)}

))}

) : null}

className="CheckboxContainer"

onClick={() =>

this.changeShipping({ [k]: i })

}

>

{shipOption.carrier

? shipOption.carrier.serviceType

: null}{' '}

{shipOption.name}

${shipOption.amount}

type="radio"

value={i}

className="ShippingInput"

onChange={() =>

this.setState({

shippingOption: {

...this.state.shippingOption,

[k]: i

}

})

}

checked={

this.state.shippingOption[k] === i

? true

: false

}

/>

)

})}

)

})}

) : null}

)

}}

)

}

}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值