简体   繁体   English

如何将一组对象的 reduce 和 setState 合并为一个 object

[英]How to reduce and setState of an array of objects into one object

I am trying to create a form to capture values.我正在尝试创建一个表单来捕获值。 My data will come in looking like this:我的数据将如下所示:

const dummyData = [
  { question: "what is your name?", isActive: true },
  { question: "what is your age?", isActive: true },
  { question: "what is your dob?", isActive: true }
];

I need to get values of all the inputs for the above questions.我需要获取上述问题的所有输入值。

I am trying to set formData to a state that looks like this我正在尝试将formData设置为如下所示的state

const formData = {
    whatIsYourName: '', 
    whatIsYourAge: '', 
    whatIsYourDob?: ''
};

import "./styles.css";
import { useState, useEffect } from "react";

const dummyData = [
  { question: "what is your name?", isActive: true },
  { question: "what is your age?", isActive: true },
  { question: "what is your dob?", isActive: true }
];

const App = () => {
  const [formData, setFormData] = useState({});

  const converDataToObject = () => {
//do something
};

  useEffect(() => {
    converDataToObject();
  }, []);

  return <div className="App">test</div>;
};

export default App;

Try to use this helper function to generate the desider object:尝试使用这个 helper function 来生成 desider object:

 const dummyData = [ { question: "what is your name?", isActive: true }, { question: "what is your age?", isActive: true }, { question: "what is your dob?", isActive: true } ]; const converDataToObject = () => { const result = {} for (const obj of dummyData) { result[generateKey(obj.question)] = "" } return result; }; // Generate a key from the given question const generateKey = (question) => { // Split the question by ` ` after removing the `?` const keySplit = question.toString().replaceAll("?", "").split(" "); // Capitalize each substring after the first one // and join the result into a single value return keySplit.map((s, idx) => { if (idx === 0) return s; return capitalize(s); }).join(""); } // Helper function, capitalize a string const capitalize = (s) => { return s.charAt(0).toUpperCase() + s.slice(1).toLowerCase(); } console.log(converDataToObject())

You will just need to set the formData with:您只需要将formData设置为:

setFormData(convertDataToObject())

You may want to keep everything together in state.您可能希望将所有内容放在 state 中。

whatisyourname: { question: 'What is your name?', isActive: true }  

and then add a new value property to the state when a corresponding input is updated.然后在更新相应input时将新value属性添加到 state。

That said it would be better (if you have control over the incoming data) to add a name property to the object, and use that instead, since it's much more meaningful.也就是说,最好(如果您可以控制传入数据)向 object 添加一个name属性,然后改用它,因为它更有意义。

{ name: 'name', question: 'What is your name?', isActive: true },

becomes this when it's converted, and you don't have to do any unnecessary find/replace on the key name.转换后就变成了这个,您不必对键名进行任何不必要的查找/替换。

name: { name: 'name', question: 'What is your name?', isActive: true },

 const { useEffect, useState } = React; // Small conversion function that // creates an object with nested objects function convertData(data) { const out = {}; for (const obj of data) { const key = obj.question.toLowerCase().replaceAll(/[?]+/g, ''); out[key] = obj; } return out; } function Example({ data }) { const [ form, setForm ] = useState({}); // Create the state using the conversion function useEffect(() => { const converted = convertData(data); setForm(converted); }, []); // A function to create the form // It maps over each property, and creates // the labels and inputs function createForm(form) { return Object.entries(form).map(([key, obj]) => { return ( <div className="input"> <label>{obj.question}</label> <input key={key} name={key} value={obj.value} /> </div> ); }); } // A function to handle changes to any // of the input values. Because we're using event // delegation we first check that the element that was // changed was an input, then we extract the name and value // from it, and set the new form, updating the value in the object function handleChange(e) { if (e.target.matches('input')) { const { name, value } = e.target; setForm({...form, [name]: {...form[name], value } }); } } useEffect(() => console.log(form), [form]); // Use event delegation on the div // to check for changes in the child elements return ( <div onChange={handleChange}> {createForm(form)} </div> ); } const data = [ { question: 'What is your name?', isActive: true }, { question: 'What is your age?', isActive: true }, { question: 'What is your dob?', isActive: true } ]; ReactDOM.render( <Example data={data} />, document.getElementById('react') );
 label { margin-right: 1em; }.input { margin-bottom: 0.5em; }
 <script src="https://cdnjs.cloudflare.com/ajax/libs/react/17.0.2/umd/react.production.min.js"></script> <script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/17.0.2/umd/react-dom.production.min.js"></script> <div id="react"></div>

Additional documentation附加文件

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM