【问题标题】:From checkboxes are not unchecked when form submitted提交表单时未取消选中来自复选框
【发布时间】:2022-01-11 15:18:18
【问题描述】:

我目前正在做一个 ReactJS 项目。 我有一个表单,应该 console.log 将表单字段 onSubmit 作为对象。 在那种形式中,我有几个复选框(由 RestAPI 从数据库中提取并由其他反应组件呈现)。

提交后,复选框未被取消选中。 我的问题是,当我手动取消选中它们时,它会将未选中的数据添加到数据对象中。

如何不手动取消选中提交上的复选框?

这是页面代码:


import React, { useState, useEffect } from 'react';
import FCIngredient from '../FunctionalComps/FCIngredient';
import { useNavigate } from 'react-router-dom';
import $ from 'jquery';

const apiUrl = 'https://somelocalhost/'

export default function NewRecipePage() {
    const navigate = useNavigate();
    const [ingredients, setIngredients] = useState([])
    const [recipeIngredients, setRecipeIngredients] = useState([])

    const addIngredientToRecipe = (ingredientObject) => {
        let tmpIngArr =[...recipeIngredients,ingredientObject];
        setRecipeIngredients([...tmpIngArr])
        tmpIngArr = [];
    }
    const Go2Home = () => {
        navigate('/');
    }
    const NewRecipeSubmited = (event) => {
        //$(".checkClass").attr("checked", false);//didn't work

        const recipeObject = {
            Name: event.target.recName.value,
            ImageUrl: event.target.recUrl.value,
            CoockingMethod: event.target.recMethod.value,
            CoockingTime:event.target.recTime.value
        }
        console.log('recipeObject: ',recipeObject);
        console.log('recipeIngredients: ',recipeIngredients);
        let cleaningArr = [];
        setRecipeIngredients(cleaningArr);
        event.preventDefault();

    }
  
    useEffect(() => {
        fetch(apiUrl, {
            method: 'GET',
            headers: new Headers({
                'Content-Type': 'application/json; charset=UTF-8',
                'Accept': 'application/json; charset=UTF-8'
            })
        })
            .then(res => {
                return res.json()
            })
            .then(
                (result) => {
                    setIngredients(result)
                    console.log(ingredients);
                },
                (error) => {
                });
    },[])


    return (
        <div style={{ color: 'white', width: '100%' }}>
            <h1>New Recipe</h1>
            <button onClick={Go2Home} >Back Home</button> <br />

            <form onSubmit={NewRecipeSubmited}>
                <input name="recName" type="text" placeholder='Recipe Name' /><br />
                <input name="recMethod" type="text" placeholder='Cooking Method' /><br />
                <input name="recTime" type="text" placeholder='Cooking Time' /><br />
                <input name="recUrl" type="url" placeholder='Recipe imageURL' /><br />
                <p>Please choose the ingredients for your recipe!</p>
                <div style={{ display: 'flex' }}>
                    {ingredients.map((ing) =>
                        <div>
                            <input type="checkbox" className='checkClass' onChange={() => {addIngredientToRecipe(ing)}} id={ing.IngredientId}/>
                            <FCIngredient ingredient={ing} key={ing.IngredientId} /></div>)}
                </div>
                <button type="submit">Add your new recipe!</button>

            </form>
        </div>
    )
}

【问题讨论】:

  • 为什么您没有在输入中使用选中的属性?如果您单击两次相同的复选框,您会看到选中/取消选中吗?这些问题有助于我理解问题,谢谢
  • @BruNo 选中属性 - 我通常不使用此复选框属性,我认为这是默认未选中的。如果我两次单击同一个复选框,我确实会看到显示和隐藏的 V 符号。
  • el === ing)} onChange={() => {addIngredientToRecipe(ing )}} id={ing.IngredientId}/> 尝试添加已检查的属性,我认为它应该可以解决您的问题
  • 成功了,谢谢!
  • 不客气,别忘了在评论加+号,谢谢

标签: jquery reactjs forms checkbox


【解决方案1】:

是的,代码几乎是正确的。以下是所需的更改:

  1. 您只需在每个成分对象中添加一个布尔字段 isChecked
  2. addIngredientToReceipe() 方法中切换所选成分对象的 isChecked 字段
  3. NewRecipeSubmitted 函数中,将每个成分对象的isChecked 设置为false,然后使用修改后的数组调用setIngredients()

检查内联 cmets 以遵循该方法:

import React, { useState, useEffect } from 'react';
import FCIngredient from '../FunctionalComps/FCIngredient';
import { useNavigate } from 'react-router-dom';

const apiUrl = 'https://somelocalhost/'

export default function NewRecipePage() {
    const navigate = useNavigate();
    const [ingredients, setIngredients] = useState([])
    const [recipeIngredients, setRecipeIngredients] = useState([])

    const addIngredientToRecipe = (ingredientObject) => {
        let tmpIngArr =[...recipeIngredients,ingredientObject];
        setRecipeIngredients([...tmpIngArr])
        // 3. Find the ingredient in the array and toggle the checked status
        let newIngredients = [...ingredients];
        for (let i = 0; i < newIngredients.length; i++) {
            if (newIngredients[i].IngredientId === ingredientObject.IngredientId) {
                newIngredients[i].isChecked = !newIngredients[i].isChecked;
                break;
            }
        }
        // 4. Update ingredients' state
        setIngredients(newIngredients);
        tmpIngArr = [];
    }
    const Go2Home = () => {
        navigate('/');
    }
    const NewRecipeSubmited = (event) => {
        const recipeObject = {
            Name: event.target.recName.value,
            ImageUrl: event.target.recUrl.value,
            CoockingMethod: event.target.recMethod.value,
            CoockingTime:event.target.recTime.value
        }
        console.log('recipeObject: ',recipeObject);
        console.log('recipeIngredients: ',recipeIngredients);
        let cleaningArr = [];
        setRecipeIngredients(cleaningArr);
        // 5. Loop through each ingredients and set the isChecked to false
        let newIngredients = [...ingredients];
        for (let i = 0; i < newIngredients.length; i++) {
            newIngredients[i].isChecked = false;
        }
        // 6. Update ingredients' state
        setIngredients(newIngredients);
        event.preventDefault();

    }
  
    useEffect(() => {
        fetch(apiUrl, {
            method: 'GET',
            headers: new Headers({
                'Content-Type': 'application/json; charset=UTF-8',
                'Accept': 'application/json; charset=UTF-8'
            })
        })
            .then(res => {
                return res.json()
            })
            .then(
                (result) => {
                    // 1. Note the new field `isChecked` here
                    setIngredients(result.map(i => ({...i, isChecked: false})))
                    console.log(ingredients);
                },
                (error) => {
                });
    },[])


    return (
        <div style={{ color: 'white', width: '100%' }}>
            <h1>New Recipe</h1>
            <button onClick={Go2Home} >Back Home</button> <br />

            <form onSubmit={NewRecipeSubmited}>
                <input name="recName" type="text" placeholder='Recipe Name' /><br />
                <input name="recMethod" type="text" placeholder='Cooking Method' /><br />
                <input name="recTime" type="text" placeholder='Cooking Time' /><br />
                <input name="recUrl" type="url" placeholder='Recipe imageURL' /><br />
                <p>Please choose the ingredients for your recipe!</p>
                <div style={{ display: 'flex' }}>
                    {ingredients.map((ing) =>
                        <div>
                            {/* 2. Note the controlled checkbox here */}
                            <input type="checkbox" className='checkClass' checked={ing.isChecked} onChange={() => {addIngredientToRecipe(ing)}} id={ing.IngredientId}/>
                            <FCIngredient ingredient={ing} key={ing.IngredientId} /></div>)}
                </div>
                <button type="submit">Add your new recipe!</button>

            </form>
        </div>
    )
}

【讨论】:

  • 事情是成分Arr 是从具有固定字段的数据库中检索的(并用于项目中的其他组件)。你知道有一种方法可以在页面本身的成分对象中添加一个字段并且不会影响数据移动到其他组件吗?
  • 是的,创建另一个钩子,这是一个将成分 ID 映射到 isChecked 状态的对象。假设你称之为ingredientIdChecked。因此,每次触发某个事件时,您将修改该单独的对象,而不是修改原始的 ingredients 数组。并且这个对象将仅限于这个组件。
【解决方案2】:

@Borni.Mr 帮助我弄清楚了这一点: 通过给每个复选框一个“checked”属性,jQuery.att.checked 现在可以工作了:

原代码:

<input type="checkbox" className='checkClass' onChange={() => {addIngredientToRecipe(ing)}} id={ing.IngredientId}/>

固定代码:

<input type="checkbox" className='checkClass' checked={recipeIngredients.some((el) => el === ing)} onChange={() => {addIngredientToRecipe(ing)}} id={ing.IngredientId}/>

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2013-01-21
    • 1970-01-01
    • 2012-05-23
    • 2017-09-19
    • 2011-02-26
    • 1970-01-01
    • 2023-02-17
    • 1970-01-01
    相关资源
    最近更新 更多