使用 useState React hook 时从状态获取空数据

2024-01-03

我偶然发现了 useState 范围的问题。我正在尝试创建一个动态引导表单,用户可以在其中向组添加更多行(这些行将包含与能源相关的数据)。因此,当我添加 2+ 行并开始更改输入值时,输入环境数据函数触发空数据(最后一个console.log)。我的错误在哪里?为什么状态数据( groupsData.group0.rows 数组)为空?

const { useState, useEffect } = React;

const App = () => {

const [ defaultData, ] = useState(
    {
        envName: undefined,
        heatingCosts: 0,
        waterCosts: 0,
        gasCosts: 0,
        environmentCosts: 0,
        frazzle: 0
    }
);
const [ groupsData, setGroupsData ] = useState( {
    group0: {
        id: 0,
        rowsAmount: 0,
        rows: []
    }
} );

// *enterEnvironmentData* function fires when input fields are changed

const enterEnvironmentData = (event) => {
    console.log(event.target.value);
    const group = event.target.getAttribute('data-group'),
        row = event.target.getAttribute('data-row');
    
    console.log("groupsData - ", groupsData);
    console.log("data-group - ", group);
    console.log("data-row - ", row);
    console.log("groupsData[", group, "]", groupsData[group]);
    console.log("groupsData[", group, "].rows", groupsData[group].rows); // rows array is empty ???
};

let [ environment, setEnvironment] = useState( {
    group0: [],
    group1: []
} );

// *toggleChangeRowsAmount* fires when changing Form.Control's value (elements amount)

const toggleChangeRowsAmount = (event) => {
    console.log(event.target);
    let value = +event.target.value,
        name = event.target.name;

    if ( value <= 0 ) {
        value = 0;
    } else {
        setGroupsData({
            ...groupsData,
            [name]: { ...groupsData[name], rowsAmount: value }
        })
    }
};

// *addRows* fires when clicking on "Add" button

const addRows = (event) => {
    const name = event.target.getAttribute('name'),
        rows = groupsData[name].rowsAmount,
        length = groupsData[name].rows.length;
    let arr = [],
        rowNames = [];
    
    for (let i = length; i < rows+length; i++) {
        let newRow = `row${i}`;
        rowNames.push(newRow);
        arr.push(
            {
                [newRow]: defaultData
            }
        );
    }

    setGroupsData({
        ...groupsData,
        [name]: {
            ...groupsData[name],
            rows: [
                ...groupsData[name].rows,
                ...arr
            ]
        }
    });

    let items = [];
    
    for (let i = 0; i < arr.length; i++ ) {
        let rn = rowNames[i];
        items.push(
            <div key={ rowNames[i] }>
                <div>
                    <label>
                        Environment
                    </label>
                    <input
                        type="text"
                        data-group={ name }
                        data-row={ rn }
                        value={ arr[i][rn].envName }
                        onChange={ enterEnvironmentData }
                    />
                </div>
                <div>
                    <label>
                        Heating Costs
                    </label>
                    <input
                        type="number"
                        data-group={ name }
                        data-row={ rn }
                        value={ arr[i][rn].heatingCosts }
                        onChange={ enterEnvironmentData }
                    />
                </div>
                <div>
                    <label>
                        Water Costs
                    </label>
                    <input
                        type="number"
                        data-group={ name }
                        data-row={ rn }
                        value={ arr[i][rn].waterCosts }
                        onChange={ enterEnvironmentData }
                    />
                </div>
                <div>
                    <label>
                        Gas Costs
                    </label>
                    <input
                        type="number"
                        data-group={ name }
                        data-row={ rn }
                        value={ arr[i][rn].gasCosts }
                        onChange={ enterEnvironmentData }
                    />
                </div>
                <div>
                    <label>
                        Environment Costs
                    </label>
                    <input
                        type="number"
                        data-group={ name }
                        data-row={ rn }
                        value={ arr[i][rn].environmentCosts }
                        onChange={ enterEnvironmentData }
                    />
                </div>
                <div>
                    <label>
                        Frazzle
                    </label>
                    <input
                        type="number"
                        data-group={ name }
                        data-row={ rn }
                        value={ arr[i][rn].frazzle }
                        onChange={ enterEnvironmentData }
                    />
                </div>
            </div>
        );
    };

    setEnvironment({
        ...environment,
        [name]: [
            ...environment[name],
            ...items
        ]
    });
};

useEffect(
    () => {
        console.log("groupsData - ", groupsData, ", environment - ", environment);
    },
    [ groupsData, environment ]
)
    
return (
    <div className="EntryForm">
        <div className="container">
            <form>
                <div key="group0" >
                    <h4>
                        Group
                    </h4>
                    <label>
                        Elements Amount                      
                        <input
                            type="number"
                            name="group0"
                            value={ groupsData["group0"].rowsAmount }
                            onChange={ toggleChangeRowsAmount }
                        />
                        <button
                            name="group0"
                            onClick={ addRows }
                        >
                            Add
                        </button>
                    <label>
                    {
                        environment["group0"].map( env => env)
                    }
                </div>
            </Form>
        </div>            
    </div>
)
};
ReactDOM.render(<App />, document.querySelector('.react'));
<script crossorigin src="https://unpkg.com/react@16/umd/react.development.js"></script>
<script crossorigin src="https://unpkg.com/react-dom@16/umd/react-dom.development.js"></script>  
<div class="react"></div>

附:此表格尚未提交任何内容。

我注意到添加行时必要的数据不为空至少两次


None

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

使用 useState React hook 时从状态获取空数据 的相关文章

  • 以编程方式更改 Redux-Form 字段值

    当我使用redux formv7 我发现没有办法设置字段值 现在在我的form 我有两个select成分 当第一个时 第二个的值就会很清楚select元件值改变 在类渲染中 div div site div div div div
  • 如何发送和接收大型 JSON 数据

    我对全栈开发比较陌生 目前正在尝试找出一种有效的方法send and fetch我的前端 React 和后端 Express 之间存在大量数据 同时最大限度地减少内存使用 具体来说 我正在构建一个地图应用程序 它需要我处理大型 JSON 文
  • 如何使用 Coffeescript 在 React 中渲染 HTML 标签?

    我目前正在学习 ReactJS 以及如何使用 Ruby on Rails 作为其后端 所以如果我做出愚蠢的假设 我深表歉意 请随意责骂我 我正在关注一个教程 其中作者使用 Coffeescript 而不是 ES6 来处理他的 ReactJS
  • 如何删除 Material React Modal 中的蓝色边框?

    我正在用这个反应材料模态 https material ui com pt components modal 在演示示例中 您可以看到当您打开模式时 有一个蓝色边框 有办法去掉吗 我在 Modal Api 中看到具有该属性disableAu
  • 使用 ref 触发反应 dropzone 不起作用

    我正在实现这个库 https github com felixrieseberg React Dropzone Component https github com felixrieseberg React Dropzone Compone
  • 如何在reactjs中禁用未来日期?

    我没有使用任何日期选择器 代码仍然工作正常 到目前为止 我已经选择了输入类型 一切正常 现在我想禁用未来的日期 我怎么做 div div
  • 使用 React.js + Express.js 发送电子邮件

    我在 ES6 中使用 React js 构建了一个 Web 应用程序 我目前想要创建一个基本的 联系我们 页面并想要发送电子邮件 我是 React 新手 刚刚发现我实际上无法使用 React 本身发送电子邮件 我正在遵循教程nodemail
  • react-route,react-hot-loader.webpack(您无法更改 ;它将被忽略)

    这是我的第一个项目react react router react hot loader webpack dev server and webpack 当我更改react组件中的代码时 热加载器生效 但同时控制台告诉我一个警告 您无法更改
  • 在旧浏览器上使用 Fetch 的 ReactJS

    我正在使用 Webpack 和 Babel 实现 React JS 但是 我在让 Fetch 与 IE 11 配合使用时遇到问题 我的 babelrc 文件中有以下内容 presets env stage 0 react 以及我的 webp
  • ReactJS - Redux Form - 如何根据单选字段元素有条件地显示/隐藏元素?

    我对 Redux 比较陌生 我有一个表单 其中有一些无线电输入 是 或 否 基本上 我想根据该无线电输入选择有条件地显示包含另一个 redux 表单字段的另一个元素 有直接的方法可以做到这一点吗 我想检查一下formProps site v
  • 使 Material UI Grid 项目的子项拉伸以适合父容器的剩余高度

    1 现状 我有一个包含 4 个网格项的 Material UI 网格容器 每个 Grid 项中都有一个 Typography 组件 其中包含标题和包含一些内容的 Card 如下所示 2 期望的外观 我希望卡片填充网格项目的剩余高度并且不超过
  • ReactCSSTransitionGroup 组件WillLeave 未调用

    我尝试使用 ReactCssTransition 但不知何故该事件没有被调用 componentWillLeave 这是我的组件 import React Component from react import TransitionGrou
  • React Native:加载图像后应用程序性能不佳

    加载图像似乎没有问题 但是加载完毕后就出现问题了 在我的应用程序中 我在整个游戏中一张一张地加载卡片图像 一旦我加载了 40 张卡片图像 整个应用程序就会变得很慢 它总是发生在第 40 个图像处 当我在第 40 个图像之后继续加载更多卡片图
  • 使用 Flask/WTForms 和 React 进行 CSRF 保护

    有没有人成功地为使用 React 作为受控组件 提交到 Flask 后端 最好使用 WTForms 的表单实现了 CSRF 保护 我看过很多部分答案 其中一个是关于 Django 的 但找不到任何关于 Flask 的明确答案 我的大问题似乎
  • Redux-saga 从操作中获取数据返回patternOrChannel 未定义

    我需要将动态数据从屏幕发送到操作 减速器 并使用该数据从 API 获取数据 但是当我在我的rootSaga我会收到这样的错误 在检查 take patternOrChannel 时未捕获 patternOrChannel 未定义未捕获在 r
  • React-redux useDispatch() 未捕获类型错误

    我正在尝试创建一个简单的组件来使用 React Redux 钩子分派操作useDispatch 我收到一个错误 我已将组件修剪到发生错误的位置 当调用 useDispatch 函数时会发生这种情况 import useDispatch fr
  • HTMLImageElement 作为 React Child 无效

    我正在尝试异步加载图像 并且仅在加载图像后才将其显示在 React 应用程序中 componentDidMount const img new Image img onload gt this setState originalImage
  • 如何访问另一个 mobx 商店中的 mobx 商店?

    假设以下结构 stores RouterStore js UserStore js index js each of Store jsfiles 是一个 mobx 存储类 包含 observable and action index js只
  • React无限滚动scrollableTarget动态获取id?

    我在我的项目中使用react infinite scroll component 如何让scrollableTarget动态获取item id 我试过这样scrollableTarget item id 但它不起作用 必须与该 div 具有
  • React Native - 跨屏幕传递数据

    我遇到了一些麻烦react native应用程序 我不知道如何跨屏幕传递数据 我意识到还有其他类似的问题在 SO 上得到了回答 但是这些解决方案对我来说不起作用 我正在使用StackNavigator 这是我的设置App js file e

随机推荐