当我在同一项目中单击两次时,为什么我的复选框不呈现?
Why aren't my checkboxes rendering when I click twice in the same item?
我在使复选框列表正常工作时遇到问题。
我正在从一组对象中渲染我的复选框,并正确显示它。
当我点击一个复选框时,它会正确呈现,如果我再点击另一个复选框,它会正常工作。
当我点击一个复选框,然后再次点击同一个复选框时,就会出现此问题。即使状态发生变化,它也不会重新渲染。所以当我点击另一个复选框时,所有内容都会重新呈现,并且之前被点击两次的复选框也会更新。
我的 products.js 文件:
const products = [
{name: "CZ15B29XTD", img: "", checked: false},
{name: "CZ16B17IPRO", img: "", checked: false},
{name: "CZ26B47I2X", img: "", checked: false},
{name: "CZ36B96I2X", img: "", checked: false},
{name: "CZ37B39I2X", img: "", checked: false},
{name: "CZ37B60IPRO", img: "", checked: false},
{name: "CZ48B18IPRO", img: "", checked: false},
{name: "CZ58B23I2X", img: "", checked: false},
{name: "2607XTD", img: "", checked: false},
]
export default products
我的 Forms.jsx 文件(在 App.js 内呈现,并接收数据和 setThanks 作为道具 - 这些不相关,因为它们不用于复选框)
import React, { useState } from 'react'
import Select from 'react-select'
import axios from 'axios'
import products from '../products'
function Form({ data, setThanks }) {
// Configure states
const [state, setState] = useState('')
const [city, setCity] = useState('')
const [customer, setCustomer] = useState('')
const [name, setName] = useState('')
const [email, setEmail] = useState('')
const [errMessage, setErrMessage] = useState(null)
const [productsState, setProductsState] = useState(products)
const [selectedValue, setSelectedValue] = useState(null);
// Configure options
let statesArr = []
let citiesArr = []
let customersArr = []
// Populate the stateArr with all the possible states
data.forEach(item => {
statesArr.push(item.state)
citiesArr.push(item.city)
customersArr.push(item.customer)
})
// Remove duplicates
const states = [...new Set(statesArr)].sort()
const filteredCities = data.filter(item => item.state === state)
// Add all cities to the citiesArr
citiesArr = filteredCities.map(function(obj){
return obj.city;
})
// Remove duplicates and sort
const singleCities = filteredCities.filter(function (el, i, arr) {
return citiesArr.indexOf(el.city) === i;
});
const sortedCities = singleCities.sort((a, b) => a.city < b.city? -1 : 1)
const filteredCustomers = data.filter(item => item.state === state && item.city === city)
// Add all cities to the customersArr
customersArr = filteredCustomers.map(function(obj){
return obj.city;
})
// Remove duplicates and sort
const singlesCustomer = filteredCustomers.filter(function (el, i, arr) {
return customersArr.indexOf(el.city) === i;
});
const sortedCustomers = singlesCustomer.sort((a, b) => a.city < b.city? -1 : 1)
// HANDLER functions
// ***********************************
const handleStateChange = (e) => {
setState(e.value)
setCity(null)
setCustomer(null)
}
const handleCityChange = (e) => {
setCity(e.value)
setCustomer(null)
}
const handleCustomerChange = (e) => {
setCustomer(e.value)
}
const handleChangeName = e => {
setName(e.target.value)
}
const handleChangeEmail = e => {
setEmail(e.target.value)
}
const handleCheckboxChange = (e, product) => {
setSelectedValue(e.target.value)
let checkboxList = productsState
checkboxList.forEach(chkItem=>{
if(chkItem === product){
chkItem['checked'] = !chkItem['checked'];
}
})
setProductsState(checkboxList)
console.log(productsState)
}
console.log(selectedValue)
const handleSubmit = e => {
e.preventDefault()
if(name && state && city && customer) {
axios.post('removed',{
"data": {
"Nome": name,
"Email": email,
"Estado": state,
"Cidade": city,
"Distribuidor": customer,
"Email Sent": "false",
"Customer Email Sent": "false"
}
}).then( response => {
console.log(response.data);
setThanks(true)
});
}
else {
setErrMessage('Por favor preencher todos os campos acima')
}
}
// Log all the values
console.log(state, city, customer, name, email)
return (
<div className="form-container">
<h4>Nome Completo</h4>
<input type="text" id="client-name" name="client-name" placeholder="Digite seu nome" onChange={handleChangeName} required/>
<h4>Email</h4>
<input type="text" id="client-email" name="client-email" placeholder="Digite seu email" onChange={handleChangeEmail} required/>
<h4>Selecione o Estado</h4>
<Select
name="form-name"
value={{label: state, key:'state-key'}}
options={states.map((state) => {
return {value: state, label: state}
})}
onChange={handleStateChange}
/>
{state &&
<div className="city-select">
<h4>Selecione a Cidade</h4>
<Select
name="form-city"
value={{label: city, key:'city-key'}}
options={sortedCities.map((item) => {
return {value: item.city, label: item.city}
})}
onChange={handleCityChange}
/>
</div> }
{state && city &&
<div className="customer-select">
<h4>Selecione o Canal</h4>
<Select
name="form-customer"
value={{label: customer, key:'customer-key'}}
options={sortedCustomers.map((item) => {
return {value: item.customer, label: item.customer}
})}
onChange={handleCustomerChange}
/>
</div> }
<h4>Selecione os Produtos</h4>
{productsState.map(product => {
return (
<div key={product.name}>
<input type="checkbox"
id={product.name}
name={product.name}
value={product.name}
checked={product.checked}
onChange={(e) => handleCheckboxChange(e, product)}
/>
<label htmlFor={product.name}> {product.name}</label><br/>
</div>
)})}
<button onClick={handleSubmit}> Enviar </button>
<h4 className="error-message">{errMessage}</h4>
</div>
)
}
export default Form
我已经删除了我正在发布数据的 url,而且我仍然没有发送复选框数据,因为它不起作用。
handleCheckboxChange 是当复选框 select (onChange) 时调用的函数的名称。
这是我的第一个问题,如果格式不是最好的或需要更多信息,我们深表歉意。
有人能帮帮我吗?提前致谢!
我很好奇从当前状态创建 new 数组是否可行。目前,做 let checkboxList = productsState
是对状态的直接引用,不应该直接改变。不久前我遇到过类似的问题,React 没有给出你正在直接改变状态的警告,这会导致奇怪的行为。
let checkboxList = [...productsState]
checkboxList.forEach(chkItem=>{
if(chkItem === product){
chkItem['checked'] = !chkItem['checked'];
}
})
我在使复选框列表正常工作时遇到问题。
我正在从一组对象中渲染我的复选框,并正确显示它。 当我点击一个复选框时,它会正确呈现,如果我再点击另一个复选框,它会正常工作。
当我点击一个复选框,然后再次点击同一个复选框时,就会出现此问题。即使状态发生变化,它也不会重新渲染。所以当我点击另一个复选框时,所有内容都会重新呈现,并且之前被点击两次的复选框也会更新。
我的 products.js 文件:
const products = [
{name: "CZ15B29XTD", img: "", checked: false},
{name: "CZ16B17IPRO", img: "", checked: false},
{name: "CZ26B47I2X", img: "", checked: false},
{name: "CZ36B96I2X", img: "", checked: false},
{name: "CZ37B39I2X", img: "", checked: false},
{name: "CZ37B60IPRO", img: "", checked: false},
{name: "CZ48B18IPRO", img: "", checked: false},
{name: "CZ58B23I2X", img: "", checked: false},
{name: "2607XTD", img: "", checked: false},
]
export default products
我的 Forms.jsx 文件(在 App.js 内呈现,并接收数据和 setThanks 作为道具 - 这些不相关,因为它们不用于复选框)
import React, { useState } from 'react'
import Select from 'react-select'
import axios from 'axios'
import products from '../products'
function Form({ data, setThanks }) {
// Configure states
const [state, setState] = useState('')
const [city, setCity] = useState('')
const [customer, setCustomer] = useState('')
const [name, setName] = useState('')
const [email, setEmail] = useState('')
const [errMessage, setErrMessage] = useState(null)
const [productsState, setProductsState] = useState(products)
const [selectedValue, setSelectedValue] = useState(null);
// Configure options
let statesArr = []
let citiesArr = []
let customersArr = []
// Populate the stateArr with all the possible states
data.forEach(item => {
statesArr.push(item.state)
citiesArr.push(item.city)
customersArr.push(item.customer)
})
// Remove duplicates
const states = [...new Set(statesArr)].sort()
const filteredCities = data.filter(item => item.state === state)
// Add all cities to the citiesArr
citiesArr = filteredCities.map(function(obj){
return obj.city;
})
// Remove duplicates and sort
const singleCities = filteredCities.filter(function (el, i, arr) {
return citiesArr.indexOf(el.city) === i;
});
const sortedCities = singleCities.sort((a, b) => a.city < b.city? -1 : 1)
const filteredCustomers = data.filter(item => item.state === state && item.city === city)
// Add all cities to the customersArr
customersArr = filteredCustomers.map(function(obj){
return obj.city;
})
// Remove duplicates and sort
const singlesCustomer = filteredCustomers.filter(function (el, i, arr) {
return customersArr.indexOf(el.city) === i;
});
const sortedCustomers = singlesCustomer.sort((a, b) => a.city < b.city? -1 : 1)
// HANDLER functions
// ***********************************
const handleStateChange = (e) => {
setState(e.value)
setCity(null)
setCustomer(null)
}
const handleCityChange = (e) => {
setCity(e.value)
setCustomer(null)
}
const handleCustomerChange = (e) => {
setCustomer(e.value)
}
const handleChangeName = e => {
setName(e.target.value)
}
const handleChangeEmail = e => {
setEmail(e.target.value)
}
const handleCheckboxChange = (e, product) => {
setSelectedValue(e.target.value)
let checkboxList = productsState
checkboxList.forEach(chkItem=>{
if(chkItem === product){
chkItem['checked'] = !chkItem['checked'];
}
})
setProductsState(checkboxList)
console.log(productsState)
}
console.log(selectedValue)
const handleSubmit = e => {
e.preventDefault()
if(name && state && city && customer) {
axios.post('removed',{
"data": {
"Nome": name,
"Email": email,
"Estado": state,
"Cidade": city,
"Distribuidor": customer,
"Email Sent": "false",
"Customer Email Sent": "false"
}
}).then( response => {
console.log(response.data);
setThanks(true)
});
}
else {
setErrMessage('Por favor preencher todos os campos acima')
}
}
// Log all the values
console.log(state, city, customer, name, email)
return (
<div className="form-container">
<h4>Nome Completo</h4>
<input type="text" id="client-name" name="client-name" placeholder="Digite seu nome" onChange={handleChangeName} required/>
<h4>Email</h4>
<input type="text" id="client-email" name="client-email" placeholder="Digite seu email" onChange={handleChangeEmail} required/>
<h4>Selecione o Estado</h4>
<Select
name="form-name"
value={{label: state, key:'state-key'}}
options={states.map((state) => {
return {value: state, label: state}
})}
onChange={handleStateChange}
/>
{state &&
<div className="city-select">
<h4>Selecione a Cidade</h4>
<Select
name="form-city"
value={{label: city, key:'city-key'}}
options={sortedCities.map((item) => {
return {value: item.city, label: item.city}
})}
onChange={handleCityChange}
/>
</div> }
{state && city &&
<div className="customer-select">
<h4>Selecione o Canal</h4>
<Select
name="form-customer"
value={{label: customer, key:'customer-key'}}
options={sortedCustomers.map((item) => {
return {value: item.customer, label: item.customer}
})}
onChange={handleCustomerChange}
/>
</div> }
<h4>Selecione os Produtos</h4>
{productsState.map(product => {
return (
<div key={product.name}>
<input type="checkbox"
id={product.name}
name={product.name}
value={product.name}
checked={product.checked}
onChange={(e) => handleCheckboxChange(e, product)}
/>
<label htmlFor={product.name}> {product.name}</label><br/>
</div>
)})}
<button onClick={handleSubmit}> Enviar </button>
<h4 className="error-message">{errMessage}</h4>
</div>
)
}
export default Form
我已经删除了我正在发布数据的 url,而且我仍然没有发送复选框数据,因为它不起作用。
handleCheckboxChange 是当复选框 select (onChange) 时调用的函数的名称。
这是我的第一个问题,如果格式不是最好的或需要更多信息,我们深表歉意。
有人能帮帮我吗?提前致谢!
我很好奇从当前状态创建 new 数组是否可行。目前,做 let checkboxList = productsState
是对状态的直接引用,不应该直接改变。不久前我遇到过类似的问题,React 没有给出你正在直接改变状态的警告,这会导致奇怪的行为。
let checkboxList = [...productsState]
checkboxList.forEach(chkItem=>{
if(chkItem === product){
chkItem['checked'] = !chkItem['checked'];
}
})