Javascript React JS,更新从地图渲染的特定字段
我有一个循环(使用Javascript React JS,更新从地图渲染的特定字段,javascript,reactjs,react-hooks,Javascript,Reactjs,React Hooks,我有一个循环(使用Array.map),它输出一组具有唯一id/键的表单。我现在需要能够唯一地编辑/提交它们 默认情况下,所有字段都应为空 目前,我还没有弄清楚如何在更改后区分它们,从而使所有字段的状态都相同 我需要每个字段分别使用其唯一的数据进行更新 基本上,我有一堆“部分”,在每个“部分”的内部,我想写文章任务 我正在运行最新的React JS,并且正在使用钩子 我将应用程序的这一部分构建如下: 父级(从DB获取节的数据并将其置于状态) 部分列表(使用来自家长的道具,映射输入和一些设计内容)
Array.map
),它输出一组具有唯一id/键的表单。我现在需要能够唯一地编辑/提交它们
默认情况下,所有字段都应为空
目前,我还没有弄清楚如何在更改后区分它们,从而使所有字段的状态都相同
我需要每个字段分别使用其唯一的数据进行更新
基本上,我有一堆“部分”,在每个“部分”的内部,我想写文章任务
我正在运行最新的React JS,并且正在使用钩子
我将应用程序的这一部分构建如下:
父级(从DB获取节的数据并将其置于状态)
部分列表(使用来自家长的道具,映射输入和一些设计内容)
输入表单,由地图渲染。(这些是我想要的唯一表单。)
这是我试过的代码。包括索引和获取唯一的_id等
在父级内部
<ProjectSections Sections={getProjectSections}
SetSections={setProjectSections} />
章节列表
function ProjectSections(props) {
const setSectionData = props.SetSections;
const SectionData = props.Sections;
const blankTask = {taskname: ""}
const [task, setTask] = useState({taskname: ""})
const [taskidx, setTaskidx] = useState({idx: ""})
console.log(task, taskidx)
const taskInputChange = (e) => {
// onChange={e => [props.SetTask({taskname: e.currentTarget.value})][props.SetIDX(e.currentTarget.dataset.idx)]}
e.preventDefault();
setTask({taskname: e.target.value})
console.log(e.target.dataset.idx)
// const updatedTasks = [e.currentTarget.dataset.idx][e.target.className] = e.target.value;
// setTask(updatedTasks)
// updatedTasks[e.target.dataset.idx][e.target.c] = e.target.value;
// console.log(updatedTasks)
}
const addTask = (e) => {
e.preventDefault();
// This is where I will post to the database
};
const TheSectionList = SectionData.map((project, idx) =>
<div key={project._id}>
<p className="is-size-5">{project.sectionname}</p>
<AddTaskForm
IDX={idx}
Submit={addTask}
SetTask={setTask}
theTask={task}
SetIDX={setTaskidx}
inputChange={taskInputChange}
/>
</div>
)
return (
<>
{TheSectionList}
</>
)
}
export default ProjectSections;
功能项目部分(道具){
const setSectionData=props.SetSections;
const SectionData=道具节;
常量blankTask={taskname:}
const[task,setTask]=useState({taskname:“})
const[taskidx,setTaskidx]=useState({idx:'})
console.log(任务,taskidx)
const taskInputChange=(e)=>{
//onChange={e=>[props.SetTask({taskname:e.currentTarget.value})][props.SetIDX(e.currentTarget.dataset.idx)]}
e、 预防默认值();
setTask({taskname:e.target.value})
console.log(e.target.dataset.idx)
//const updateTasks=[e.currentTarget.dataset.idx][e.target.className]=e.target.value;
//setTask(更新任务)
//updatedTasks[e.target.dataset.idx][e.target.c]=e.target.value;
//日志(更新的任务)
}
const addTask=(e)=>{
e、 预防默认值();
//这是我将发布到数据库的地方
};
const TheSectionList=SectionData.map((项目,idx)=>
{project.sectionname}
)
返回(
{TheSectionList}
)
}
导出默认项目节;
表格(AddTaskForm)
函数AddTaskForm(道具){
返回(
);
};
导出默认AddTaskForm;
现在,每当我更新(写入)任何表单时,它们都会发生变化,尽管控制台日志中正确显示了
idx
。您的应用程序的范围可能比您在原始帖子中建议的要大得多
无论如何,我已经为您创建了一个中等大小的原型。这应该演示如何封装每个部分
,以便将它们的任务列表和功能隔离到各自的上下文中
请参见此处了解:
总共只有3个子组件和1个父组件
index.js
主要部分状态在此处进行管理。所有状态更新函数都是从这里派生的
import React,{useState}来自“React”;
从“react dom”导入react dom;
从“/AddSectionForm”导入AddSectionForm;
从“/ProjectSections”导入项目节;
导入“/styles.css”;
函数App(){
const[sections,setSections]=使用状态([
{
id:1,
节名:“家务活”,
任务:[{id:1,desc:“清除垃圾”,编辑:false}]
}
]);
const addNewSection=sectionName=>{
让newSection={
id:keyRandomizer(),
sectionName:sectionName,
任务:[]
};
设置节([…节,新闻节]);
};
const addNewTask=(sectionId,taskName)=>{
让newTask={
id:keyRandomizer(),
任务名称,
编辑:错
};
让AllSectionScope=JSON.parse(JSON.stringify(sections));
让sectionIndex=allSectionScope.findIndex(
section=>section.id===sectionId
);
让sectionToUpdate=AllSectionScope[sectionIndex];
sectionToUpdate.tasks=[…sectionToUpdate.tasks,newTask];
设置部分([…所有部分]);
};
const UPDATETASKSDESC=(描述、节ID、任务ID)=>{
让AllSectionScope=JSON.parse(JSON.stringify(sections));
让sectionIndex=allSectionScope.findIndex(
section=>section.id===sectionId
);
让sectionToUpdate=AllSectionScope[sectionIndex];
让taskIndex=sectionToUpdate.tasks.findIndex(task=>task.id==taskId);
让taskToUpdate=sectionToUpdate.tasks[taskIndex];
taskToUpdate.desc=desc;
设置部分([…所有部分]);
};
const-toggleTaskEditMode=(节ID,任务ID)=>{
让AllSectionScope=JSON.parse(JSON.stringify(sections));
让sectionIndex=allSectionScope.findIndex(
section=>section.id===sectionId
);
让sectionToUpdate=AllSectionScope[sectionIndex];
让taskIndex=sectionToUpdate.tasks.findIndex(task=>task.id==taskId);
让taskToUpdate=sectionToUpdate.tasks[taskIndex];
taskToUpdate.editing=!taskToUpdate.editing;
设置部分([…所有部分]);
};
常量键随机化器=()=>{
让随机键=”;
让角色=
“ABCDEFGHIJKLMNOPQRSTUVWXYZABCDFGHIJKLMNOPQRSTUVXYZ0123456789”;
对于(变量i=0;i<5;i++){
randomKey+=字符。字符(
Math.floor(Math.random()*characters.length)
);
}
返回随机键;
};
返回(
);
}
const rootElement=document.getElementById(“根”);
render(,rootElement);
AddSectionForm.js
只需添加新的节,以便在“整体节”状态中使用
import React,{useState}来自“React”;
功能AddSectionForm(道具){
const[text,setText]=useState(“”);
常量handleChange=e=>{
setText(即目标值);
};
常量handleSubmit=e=>{
e、 预防默认值();
道具。添加新闻节(文本);
};
返回(
);
}
导出默认的AddSectionForm;
项目
function AddTaskForm(props) {
return (
<>
<form onSubmit={props.Submit} >
<input
onChange={props.inputChange}
type="text"
placeholder="Create Homepage"
value={props.theTask.taskname}
data-idx={props.IDX}
/>
</div>
<input type="submit" value="Add Task" />
</div>
</div>
</form>
</>
);
};
export default AddTaskForm;
import React, { useState } from "react";
import ReactDOM from "react-dom";
import AddSectionForm from "./AddSectionForm";
import ProjectSections from "./ProjectSections";
import "./styles.css";
function App() {
const [sections, setSections] = useState([
{
id: 1,
sectionName: "Chores",
tasks: [{ id: 1, desc: "Take out trash", editting: false }]
}
]);
const addNewSection = sectionName => {
let newSection = {
id: keyRandomizer(),
sectionName: sectionName,
tasks: []
};
setSections([...sections, newSection]);
};
const addNewTask = (sectionId, taskName) => {
let newTask = {
id: keyRandomizer(),
desc: taskName,
editting: false
};
let allSectionsCopy = JSON.parse(JSON.stringify(sections));
let sectionIndex = allSectionsCopy.findIndex(
section => section.id === sectionId
);
let sectionToUpdate = allSectionsCopy[sectionIndex];
sectionToUpdate.tasks = [...sectionToUpdate.tasks, newTask];
setSections([...allSectionsCopy]);
};
const updateTaskDesc = (desc, sectionId, taskId) => {
let allSectionsCopy = JSON.parse(JSON.stringify(sections));
let sectionIndex = allSectionsCopy.findIndex(
section => section.id === sectionId
);
let sectionToUpdate = allSectionsCopy[sectionIndex];
let taskIndex = sectionToUpdate.tasks.findIndex(task => task.id === taskId);
let taskToUpdate = sectionToUpdate.tasks[taskIndex];
taskToUpdate.desc = desc;
setSections([...allSectionsCopy]);
};
const toggleTaskEditMode = (sectionId, taskId) => {
let allSectionsCopy = JSON.parse(JSON.stringify(sections));
let sectionIndex = allSectionsCopy.findIndex(
section => section.id === sectionId
);
let sectionToUpdate = allSectionsCopy[sectionIndex];
let taskIndex = sectionToUpdate.tasks.findIndex(task => task.id === taskId);
let taskToUpdate = sectionToUpdate.tasks[taskIndex];
taskToUpdate.editting = !taskToUpdate.editting;
setSections([...allSectionsCopy]);
};
const keyRandomizer = () => {
let randomKey = "";
let characters =
"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";
for (var i = 0; i < 5; i++) {
randomKey += characters.charAt(
Math.floor(Math.random() * characters.length)
);
}
return randomKey;
};
return (
<div className="App">
<AddSectionForm addNewSection={addNewSection} />
<ProjectSections
sections={sections}
addNewTask={addNewTask}
updateTaskDesc={updateTaskDesc}
toggleTaskEditMode={toggleTaskEditMode}
/>
</div>
);
}
const rootElement = document.getElementById("root");
ReactDOM.render(<App />, rootElement);
import React, { useState } from "react";
function AddSectionForm(props) {
const [text, setText] = useState("");
const handleChange = e => {
setText(e.target.value);
};
const handleSubmit = e => {
e.preventDefault();
props.addNewSection(text);
};
return (
<form onSubmit={handleSubmit}>
<input
onChange={handleChange}
type="text"
placeholder="Create Homepage"
value={text}
/>
<input className="add-section-button" type="submit" value="Add Section" />
</form>
);
}
export default AddSectionForm;
import React from "react";
import Section from "./Section";
function ProjectSections(props) {
const createSections = () => {
const { sections, addNewTask, toggleTaskEditMode, updateTaskDesc } = props;
return sections.map(section => {
return (
<Section
section={section}
addNewTask={addNewTask}
updateTaskDesc={updateTaskDesc}
toggleTaskEditMode={toggleTaskEditMode}
/>
);
});
};
return <div>{createSections()}</div>;
}
export default ProjectSections;
import React, { useState } from "react";
const Section = ({
section,
addNewTask,
toggleTaskEditMode,
updateTaskDesc
}) => {
const [newTaskName, setTaskName] = useState("");
const handleSubmit = e => {
e.preventDefault();
addNewTask(section.id, newTaskName);
setTaskName("");
};
const handleUpdateTaskDesc = (e, sectionId, taskId) => {
updateTaskDesc(e.target.value, sectionId, taskId);
};
const handleToggle = (sectionId, taskId) => {
toggleTaskEditMode(sectionId, taskId);
};
const handleNewTaskChange = e => {
setTaskName(e.target.value);
};
return (
<div className="section">
<h4>{section.sectionName}</h4>
{section.tasks.map(task => {
return !task.editting ? (
<div className="task-item">
<label>{task.desc}</label>
<button onClick={() => handleToggle(section.id, task.id)}>
Edit
</button>
</div>
) : (
<div className="task-item">
<input
value={task.desc}
onChange={e => handleUpdateTaskDesc(e, section.id, task.id)}
/>
<button onClick={() => handleToggle(section.id, task.id)}>
Done
</button>
</div>
);
})}
{/* Add new task */}
<form onSubmit={handleSubmit}>
<input
placeholder="Add Task"
name="task"
onChange={handleNewTaskChange}
value={newTaskName}
/>
<button type="submit" disabled={!newTaskName.length}>
Add Task
</button>
</form>
</div>
);
};
export default Section;