来自儿童组件的更新列表REECT挂钩

发布于 2025-02-08 14:16:27 字数 3154 浏览 3 评论 0原文

我很陌生地反应,并且正在尝试根据用户输入添加从子组件中更新列表,它将无法正确更新。这个想法是用户能够以一种形式添加多个不同的自行车,每种自行车都具有typeagerange属性。当用户单击“添加自行车”按钮时,它会添加bikeinput组件(效果很好),并且应该将新的空自行车添加到一个自行车列表中时,该自行车将在提交表单时发送。我在添加新输入后登录了使用效果函数的自行车列表,但可以正常运行,但是当我尝试设置一辆新自行车时,它会从列表中删除除第一个元素的所有元素。再次,我很新鲜反应,所以我不确定我是否正确地使用了使用效果功能,还是还有另一种方法可以解决,但是如果您可以让我知道这会很棒。

这是与type属性相关的代码重要部分的一些片段,因为agerange应该以相同的方式工作方式:

子组件:

import { useState, useEffect } from 'react'

const initialList = {
    "id": 0,
    "type": "",
    "ageRange": ""
};

function Donate() {

    const [bikes, setBikes] = useState([initialList]);
    useEffect(() => console.log(bikes), [bikes])

    const setBikeType = (bikeType, bikeIndex) => {
        const updateBikes = bikes.map((bike) => {
            if (bike.id == bikeIndex) {
                bike.type = bikeType;
            }
            return bike;
        });
        setBikes(updateBikes);
    }

    const [bikeInputs, setBikeInputs] = useState([
        <BikeInput
            setBikeType={setBikeType}
            setBikeAgeRange={setBikeAgeRange}
            bikeIndex={0} />]);

    const addBikeForm = (e) => {
        e.preventDefault();
        var newBikeIndex = bikeInputs.length;
        setBikeInputs(bikeInputs =>
            [...bikeInputs,
                <BikeInput
                    setBikeType={setBikeType}
                    setBikeAgeRange={setBikeAgeRange}
                    bikeIndex={newBikeIndex}
                />
            ]
        );

        var newBikeId = bikes[bikes.length - 1].id + 1;
        setBikes(bikes => [...bikes, { "id": newBikeId, "type": "", "ageRange": "" }]);

    };

    return (
        <div className="bike-form-container donate-form-one">
            ...             
            <p className="input-title">Bike Info.</p>
            {bikeInputs.map((item, i) => (
                <div className="bike-input" key={i}>{item}</div>
            ))}
            <button className="add-bike-btn" onClick={addBikeForm}>
                <i class="fa-solid fa-circle-plus"></i> Add A Bike
            </button>
            ...
        </div>
    )
}

export default Donate

子零件(bikeinput):

function BikeInput(props) {
    return (
        <div className="input-container">
            <select className="form-dropdown text-input"
                defaultValue="Type"
                onChange={e => props.setBikeType(e.target.value, props.bikeIndex)} >
                <option disabled>Type</option>
                <option value="Mountain"> Mountain </option>
                <option value="Road"> Road </option>
                <option value="Cruiser"> Cruiser </option>
                <option value="Hybrid"> Hybrid </option>
                <option value="Three Wheel"> Three Wheel (Tricycle) </option>
            </select>
            ...
        </div>
   )
}

export default BikeInput

I'm pretty new to react and I'm trying to update a list from a child component based on user input add it will not update correctly. The idea is the user is able to add multiple different bikes in one form, each with a type and an ageRange property. When the user clicks an "Add Bike" button it adds BikeInput component (which works fine) and is supposed to be adding a new empty bike to a list of bikes that will be sent when the form is submitted. I console logged in a useEffect function the list of bikes after adding a new input and that works okay, but when I try to set one of the new bikes it removes all the elements from the list except the first. Again I'm pretty new to react so I'm not exactly sure if I'm using the useEffect function correctly or if there's another way to go about this, but if you could let me know that'd be amazing.

Here's some snippets of the important parts of the code that relate to the type property since the ageRange should work the same way

Parent Component:

import { useState, useEffect } from 'react'

const initialList = {
    "id": 0,
    "type": "",
    "ageRange": ""
};

function Donate() {

    const [bikes, setBikes] = useState([initialList]);
    useEffect(() => console.log(bikes), [bikes])

    const setBikeType = (bikeType, bikeIndex) => {
        const updateBikes = bikes.map((bike) => {
            if (bike.id == bikeIndex) {
                bike.type = bikeType;
            }
            return bike;
        });
        setBikes(updateBikes);
    }

    const [bikeInputs, setBikeInputs] = useState([
        <BikeInput
            setBikeType={setBikeType}
            setBikeAgeRange={setBikeAgeRange}
            bikeIndex={0} />]);

    const addBikeForm = (e) => {
        e.preventDefault();
        var newBikeIndex = bikeInputs.length;
        setBikeInputs(bikeInputs =>
            [...bikeInputs,
                <BikeInput
                    setBikeType={setBikeType}
                    setBikeAgeRange={setBikeAgeRange}
                    bikeIndex={newBikeIndex}
                />
            ]
        );

        var newBikeId = bikes[bikes.length - 1].id + 1;
        setBikes(bikes => [...bikes, { "id": newBikeId, "type": "", "ageRange": "" }]);

    };

    return (
        <div className="bike-form-container donate-form-one">
            ...             
            <p className="input-title">Bike Info.</p>
            {bikeInputs.map((item, i) => (
                <div className="bike-input" key={i}>{item}</div>
            ))}
            <button className="add-bike-btn" onClick={addBikeForm}>
                <i class="fa-solid fa-circle-plus"></i> Add A Bike
            </button>
            ...
        </div>
    )
}

export default Donate

Child Component (BikeInput):

function BikeInput(props) {
    return (
        <div className="input-container">
            <select className="form-dropdown text-input"
                defaultValue="Type"
                onChange={e => props.setBikeType(e.target.value, props.bikeIndex)} >
                <option disabled>Type</option>
                <option value="Mountain"> Mountain </option>
                <option value="Road"> Road </option>
                <option value="Cruiser"> Cruiser </option>
                <option value="Hybrid"> Hybrid </option>
                <option value="Three Wheel"> Three Wheel (Tricycle) </option>
            </select>
            ...
        </div>
   )
}

export default BikeInput

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

不羁少年 2025-02-15 14:16:27

删除您的BikeInputs状态,因为您不必保留一系列自行车的组件。只需在bikes.map内使用BikeInput组件即可渲染每个自行车选择选项。

请简化并更新您的捐赠组件代码如下:

export function Donate() {
  const [bikes, setBikes] = useState([initialList]);

  useEffect(() => console.log(bikes), [bikes]);

  const setBikeType = useCallback(
    (bikeType, bikeIndex) => {
      const updateBikes = bikes.map((bike) => {
        if (bike.id === bikeIndex) {
          bike.type = bikeType;
        }
        return bike;
      });
      setBikes(updateBikes);
    },
    [bikes]
  );

  const addBikeForm = useCallback(
    (e) => {
      e.preventDefault();
      setBikes((bikes) => {
        const newBikeId = bikes[bikes.length - 1].id + 1;
        return [...bikes, { id: newBikeId, type: "", ageRange: "" }];
      });
    },
    [setBikes]
  );

  return (
    <div className="bike-form-container donate-form-one">
      <p className="input-title">Bike Info.</p>
      {bikes.map((item, i) => (
        <div className="bike-input" key={i}>
          <BikeInput bikeIndex={i} setBikeType={setBikeType} />
        </div>
      ))}
      <button className="add-bike-btn" onClick={addBikeForm}>
        <i className="fa-solid fa-circle-plus"></i> Add A Bike
      </button>
    </div>
  );
}

Remove your bikeInputs state, since you don't have to keep a collection of BikeInputs components. Just use the BikeInput component inside bikes.map to render each bike select option.

Please simplify and update your Donate component code as follows:

export function Donate() {
  const [bikes, setBikes] = useState([initialList]);

  useEffect(() => console.log(bikes), [bikes]);

  const setBikeType = useCallback(
    (bikeType, bikeIndex) => {
      const updateBikes = bikes.map((bike) => {
        if (bike.id === bikeIndex) {
          bike.type = bikeType;
        }
        return bike;
      });
      setBikes(updateBikes);
    },
    [bikes]
  );

  const addBikeForm = useCallback(
    (e) => {
      e.preventDefault();
      setBikes((bikes) => {
        const newBikeId = bikes[bikes.length - 1].id + 1;
        return [...bikes, { id: newBikeId, type: "", ageRange: "" }];
      });
    },
    [setBikes]
  );

  return (
    <div className="bike-form-container donate-form-one">
      <p className="input-title">Bike Info.</p>
      {bikes.map((item, i) => (
        <div className="bike-input" key={i}>
          <BikeInput bikeIndex={i} setBikeType={setBikeType} />
        </div>
      ))}
      <button className="add-bike-btn" onClick={addBikeForm}>
        <i className="fa-solid fa-circle-plus"></i> Add A Bike
      </button>
    </div>
  );
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文