[英]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.