Javascript 如何在全局选项卡中创建动态元素
我正在使用react hooks工作,遇到了一个问题,我现在被卡住了 每当用户Javascript 如何在全局选项卡中创建动态元素,javascript,css,reactjs,react-hooks,Javascript,Css,Reactjs,React Hooks,我正在使用react hooks工作,遇到了一个问题,我现在被卡住了 每当用户登录时,我都会得到一个json数据,因此我会创建一个顶部栏,显示用户名,当用户单击这些名称时,我会显示他们在db中创建或呈现的一些数据,这些数据我已经在数据中得到了 我从服务器获取的数据 let data= [ { "id": 1, "name": "Maxi", "myData": [ {
登录时,我都会得到一个json数据,因此我会创建一个顶部栏,显示用户名
,当用户单击这些名称时,我会显示他们在db中创建或呈现的一些数据,这些数据我已经在数据中得到了
我从服务器获取的数据
let data= [
{
"id": 1,
"name": "Maxi",
"myData": [
{
"data_name": "div1",
"data_title": "div1 tittle"
},
{
"data_name": "div1",
"data_title": "div tittle"
}
]
},
{
"id": 2,
"name": "Phill",
"myData": [
{
"data_name": "div21",
"data_title": "div21 tittle"
}
]
}
]
在我想创建新div的一侧有一个按钮,在我从顶部选择的名称内
假设我列出了顶栏
,总共有3个数据,即3个名称,那么如果数据长度小于4,我正在做的是,显示一个加号按钮来创建一个多选项卡,用户可以创建一个多选项卡,然后他们可以在每个选项卡内创建一个div
我所做的
我正在填充顶部栏,当我单击侧边按钮时,我正在所选选项卡内创建一个div
我面临的问题
- 如果数据长度小于4,我会在“更多”选项卡上提供一个加号按钮来创建(给它默认名称),但我不知道如何创建新的加号按钮
- 当我点击侧边按钮在选项卡内创建一个俯冲时,我转到另一个选项卡并再次返回,我希望创建的
div
不应被删除
- 假设我有3个选项卡(数据),所以当页面加载第一个选项卡数据时,我想显示,但它没有显示,我需要单击那里,只有它显示出来
- 如果数据为空,那么我最多可以创建4个选项卡。这也是我想要的一些想法
我将我的代码沙盒链接到这里,这样就很容易理解我做了什么以及我正在尝试做什么
在这里的代码沙盒我已经写了我所有的代码,请检查出来
我已经解释了我要做的每一件事,我知道如何编码,但没有得到任何想法或方法
如果用户没有数据,那么我将从1开始为该用户创建选项卡和嵌套元素
在每个选项卡中,为创建的每个新元素都会有一个保存按钮,所以我会这样做,我唯一的目的是在创建一个选项卡到另一个选项卡时,不要丢失ui上的数据
export default function App() {
const [active_menu, setactive_menu] = useState(0);
const [nestedData, setnestedData] = useState(null);
let data1 = [
{
id: 1,
name: "Maxi",
myData: [
{
data_name: "div1",
data_title: "div1 tittle"
},
{
data_name: "div1",
data_title: "div tittle"
}
]
},
{
id: 2,
name: "Phill",
myData: [
{
data_name: "div21",
data_title: "div21 tittle"
}
]
}
];
const Tab_click = (index, li) => {
setactive_menu(index);
setnestedData(li);
};
const Create_element = () => {
//here I don't know how to create new elements
};
const addnewTab=()=>{
}
return (
<div className="App row">
{data1.map((li, index) => (
<div className="col-4 col-sm-4 col-md-3 col-lg-3 col-xl-3" key={index}>
<div
className={
index === active_menu
? "row dashboard_single_cont_active"
: "row dashboard_single_cont"
}
onClick={() => Tab_click(index, li)}
>
<div className="dashboard_name col-10 col-sm-10 col-md-9 col-lg-10 col-xl-10">
{li.name}
</div>
<div
className={
active_menu === index
? "dashboard_option_active col-2 col-sm-2 col-md-3 col-lg-2 col-xl-2"
: "dashboard_option col-2 col-sm-2 col-md-3 col-lg-2 col-xl-2"
}
align="center"
></div>
</div>
</div>
))}
{data1.length < 4 && (
<span
onClick={addnewTab}
>ADD</span>
)}
<div className="col-11 col-sm-11 col-md-11 col-lg-11 col-xl-11">
<div className="row">
{nestedData !== null &&
nestedData.myData.map((li, index) => (
<div className="col-11 col-sm-11 col-md-8 col-lg-6 col-xl-6">
<NEsted data={li} />
<br></br>
</div>
))}
</div>
</div>
<RightBar Create_element={Create_element} />
</div>
);
}
导出默认函数App(){
const[活动菜单,设置活动菜单]=使用状态(0);
const[nestedData,setnestedData]=useState(null);
设data1=[
{
id:1,
姓名:“Maxi”,
我的数据:[
{
数据单元名称:“div1”,
数据标题:“第1部分标题”
},
{
数据单元名称:“div1”,
数据标题:“部门标题”
}
]
},
{
id:2,
姓名:“Phill”,
我的数据:[
{
数据名称:“div21”,
数据标题:“div21标题”
}
]
}
];
const Tab_click=(索引,li)=>{
设置活动菜单(索引);
setnestedData(li);
};
const Create_元素=()=>{
//在这里,我不知道如何创建新元素
};
常量addnewTab=()=>{
}
返回(
{data1.map((li,index)=>(
Tab_单击(索引,li)}
>
{li.name}
))}
{data1.length<4&&(
添加
)}
{nestedData!==null&&
nestedData.myData.map((li,index)=>(
))}
);
}
您面临的问题
如果数据长度小于四,我会在“更多”选项卡上提供一个加号按钮来创建(给它默认名称),但我不知道如何创建新的加号按钮
在这里,您想要获得一个新名称,即页面上带有文本输入的表单,随机生成名称,请使用提示,如下所示。调用setData
并使用功能状态更新将现有数据扩展到新数组中并附加新数据对象
const addNewTab = () => {
/**
* window.prompt is just a quick way to request input from user.
*/
const name = window.prompt('Enter Name');
/**
* logic to generate next id, but could be anything really
*/
const id = generateId();
if (name) {
setData((data) => [...data, new Data(id, name)]);
}
};
当我点击侧边按钮在选项卡内创建一个俯冲时,我转到另一个选项卡并再次返回,我希望创建的div
不应被删除
这里发生了几件事。首先,在函数体中定义了data1
,以便在每个渲染周期重置它。保持数据处于状态,数据
可以作为初始状态提供。其次,您需要添加创建的元素。通过更新状态来实现这一点
将data1
移出组件,并定义用数据初始化的本地组件状态(将渲染中的所有引用从数据
更新为数据
)
与添加新选项卡类似的方法是,获取新的数据名称和标题。这里我们调用setData
并再次使用函数状态更新,但这次我们将把现有状态映射到一个新数组。当数组索引与活动选项卡索引匹配时,这就是我们需要更新的数据对象。将其myData
扩展到一个新数组中,并附加新的数据对象。如果索引不匹配,则只返回元素
const Create_element = () => {
/**
* window.prompt is just a quick way to request input from user.
*/
const data_name = window.prompt('Enter Data Name');
const data_title = window.prompt('Enter Data Title');
if (data_name && data_title) {
setData(data => data.map((el, i) => i === active_menu ? {
...el,
myData: [...el.myData, { data_name, data_title }],
} : el))
}
};
假设我有3个选项卡(数据),所以当页面加载第一个选项卡数据时,我想显示,但它没有显示,我需要单击那里,只有它显示出来
这里的问题是由于保留了一个单独的nestedData
state对象,该对象仅在单击选项卡时更新。将新元素添加到活动选项卡的myData
arraynestedData
时不会更新。这里的解决方案是直接在UI中呈现嵌套数据
更新选项卡的onClick处理程序,只需设置活动菜单(索引)
直接从新的data
状态呈现myData
data[active_menu].myData.map((li, index) => (...
如果数据为空,那么我最多可以创建4个选项卡。这也是我想要的一些想法
有条件地呈现“添加”按钮将控制此操作
{data.length < 4 && <button onClick={addNewTab}>ADD</button>}
data[active_menu].myData.map((li, index) => (...
{data.length < 4 && <button onClick={addNewTab}>ADD</button>}
import React, { useState } from "react";
import "./styles.css";
import RightBar from "./Right_option";
import NEsted from "./Nested";
import "bootstrap/dist/css/bootstrap.min.css";
/**
* https://stackoverflow.com/questions/63814645/how-to-create-dynamic-elements-inside-global-tabs
*/
const data1 = [
{
id: 1,
name: "Maxi",
myData: [
{
data_name: "div1",
data_title: "div1 tittle"
},
{
data_name: "div1",
data_title: "div tittle"
}
]
},
{
id: 2,
name: "Phill",
myData: [
{
data_name: "div21",
data_title: "div21 tittle"
}
]
}
];
/**
* Data object constructor
* @param {number} id new data object id
* @param {string} name new data object name
* @example
* new Data(1, 'Bill')
*/
const Data = (id, name) => ({ id, name, myData: [] });
/**
* Id generator hook
* @param {number} [seed=0] initial id generator value
* @returns {function}
*/
const useIdGenerator = (seed = 0) => {
function* genId(seed = 0) {
let i = seed;
while (true) yield i++;
}
const generator = genId(seed);
return () => generator.next().value;
};
export default function App() {
const generateId = useIdGenerator(5);
const [data, setData] = useState(data1);
const [active_menu, setactive_menu] = useState(0);
const Create_element = () => {
/**
* window.prompt is just a quick way to request input from user.
*/
const data_name = window.prompt("Enter Data Name");
const data_title = window.prompt("Enter Data Title");
if (data_name && data_title) {
setData((data) =>
data.map((el, i) =>
i === active_menu
? {
...el,
myData: [...el.myData, { data_name, data_title }]
}
: el
)
);
}
};
const addNewTab = () => {
/**
* window.prompt is just a quick way to request input from user.
*/
const name = window.prompt("Enter Name");
if (name) {
setData((data) => [...data, new Data(generateId(), name)]);
}
};
return (
<div className="App row">
{data.map((li, index) => (
<div className="col-4 col-sm-4 col-md-3 col-lg-3 col-xl-3" key={index}>
<div
className={
index === active_menu
? "row dashboard_single_cont_active"
: "row dashboard_single_cont"
}
onClick={() => setactive_menu(index)}
>
<div className="dashboard_name col-10 col-sm-10 col-md-9 col-lg-10 col-xl-10">
{li.name}
</div>
<div
className={
active_menu === index
? "dashboard_option_active col-2 col-sm-2 col-md-3 col-lg-2 col-xl-2"
: "dashboard_option col-2 col-sm-2 col-md-3 col-lg-2 col-xl-2"
}
align="center"
></div>
</div>
</div>
))}
{data.length < 4 && <button onClick={addNewTab}>ADD</button>}
<div className="col-11 col-sm-11 col-md-11 col-lg-11 col-xl-11">
<div className="row">
{data[active_menu].myData.map((li, index) => (
<div
key={index}
className="col-11 col-sm-11 col-md-8 col-lg-6 col-xl-6"
>
<NEsted data={li} />
<br></br>
</div>
))}
</div>
</div>
<RightBar Create_element={Create_element} />
</div>
);
}