如何在全局标签内创建动态元素 [英] How to create dynamic elements inside global tabs

查看:52
本文介绍了如何在全局标签内创建动态元素的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在使用react挂钩,并且遇到一个问题,我现在被卡住了。


我有一个json数据,每当用户记录时,我都会获取在中,因此我创建了一个顶部栏,显示用户名,当用户单击这些名称时,我将显示他们创建的一些数据或在db中显示给他们,我已经从数据中获取的数据


我从服务器获取的我的数据

  let data = [
{
id:1,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;
}
]
}
]

我有一个按钮


因此,假设我已列出 topbar 并且总共有3个数据(即3个名称),因此,如果数据长度小于我在做什么,则显示一个加号按钮以创建另一个选项卡,因此用户可以再创建一个选项卡,然后可以在其中创建一个div每个选项卡,


我做了什么


我正在填充顶部栏以及单击侧面时按钮,我在所选标签中创建了一个 div


我正面临的问题



  • 如果数据长度小于四个,我在更多选项卡上提供一个加号按钮来创建(给它默认名称),但是我不知道该怎么办创建新的潜水表。

  • 当我单击侧面按钮在选项卡内创建一个潜水时,我转到其他选项卡并返回我希望创建的 div 不会被删除。

  • 假设我有3个标签(数据),因此当页面加载第一个标签时我想显示的数据,但没有显示,我只需要单击它就可以显示。

  • 如果数据为空,那么我最多可以创建4个标签a =想要一些想法来做。


我在这里链接我的代码沙箱,因此很容易理解我所做的事情以及我要做什么



完整代码

  import React,{useState} from react; 
import``./styles.css;

import RightBar来自 ./Right_option;
导入来自 ./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,
名称: Maxi,
myData:[
{
data_name: div1,
data_title: div1 tittle;
},
{
data_name: div1,
data_title: div tittle
}
]
},
{
id:2,
名称: Phill,
myData:[
{
data_name: div21,
data_title: div21 tittle
}
]
}
];

/ **
*数据对象构造函数
* @param {number} id新数据对象id
* @param {string}名称新数据对象名称
* @example
* new Data(1,'Bill')
* /
const Data =(id,name)=> ({id,name,myData:[]});

/ **
* ID生成器挂钩
* @param {number} [seed = 0]初始ID生成器值
* @returns {function}
* /
const useIdGenerator =(seed = 0)=> {
function * genId(seed = 0){
让我=种子;
而(true)产生i ++;
}

const generator = genId(seed);

return()=> generator.next()。value;
};

导出默认函数App(){
const generateId = useIdGenerator(5);

const [data,setData] = useState(data1);
const [active_menu,setactive_menu] = useState(0);

const Create_element =()=> {
/ **
* window.prompt只是请求用户输入的一种快速方法。
* /
const data_name = window.prompt(输入数据名称);
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只是请求用户输入的一种快速方法。
* /
const name = window.prompt( Enter Name);

if(name){
setData((data)=> [... data,new Data(generateId(),name)]);
}
};

return(
< div className =应用程序行>
{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
?行dashboard_single_cont_active
: rowdashboard_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&quo t;
}
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 =行>
{data [active_menu] .myData.map((li,index)=>(
< div
键= {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>
);
}


I am working with react hooks, And encounter a problem where I have been stuck now.

I have one json data which I am getting whenever user logs in so by that I am creating one top bar which shows user names and when user click on those names I am showing some data which they have created or present for them in db, That data I am already getting in data

MY data I am getting from server

 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"
      }
    ]
  }
]

I have one button on side on which I want to create new div, inside the name I have selected from top.

SO suppose I have listed the topbar and there are total of 3 data i.e 3 names, so if data length is smaller than 4 what I am doing, showing a plus button to create one more tab, so user can create one more tab and then they can create one div inside there each tab,

What I have done

I am populating the top bar as well as when I click on side button I am creating one div inside that selected tab.

Issues I am facing

  • if length of data is less then four I am providing a plus button to create on more tab (give it default name), but I am not getting any idea how can I create the new one.
  • when I click on side button to create one dive inside tab, and I go to other tab and come back again I want that created div should not gets deleted.
  • Suppose I have 3 tabs (data) so when page loads the first tab data I want to show, but it is not showing up I need to click there only it is showing up.
  • if the data is null then I can create up to 4 tabs this also I a=want some Idea to do it.

I am linking my code sand box here so it will be easy to understand what I have done and what I am trying to do

Code sandbox

Here in code sand box I have written all my code please check it out.

I have explained every thing what I a m trying to do, I know how to code but not getting any idea or approach.

if there is no data for user then I will start creating tabs and nested elements from 1 for that user.

in each there will be a save button for each new element created, so I will do that, my only consern is to not to loss data on ui when I go one tab to other once I created them

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>
  );
}

解决方案

Issues You are Facing

  1. If length of data is less than four I am providing a plus button to create on more tab (give it default name), but I am not getting any idea how can I create the new one.

Here you want to get a new name, i.e. a form on the page with a text input, random generate name, use a prompt as I did below. Call setData and use a functional state update to spread existing data into a new array and append a new data object.

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)]);
  }
};

  1. When I click on side button to create one dive inside tab, and I go to other tab and come back again I want that created div should not gets deleted.

A couple things going on here. First, you defined data1 in the function body so it is reset every render cycle. Keep the data in state, data can be provided as initial state. Second, you need to add the created elements. Do this by updating state.

Move data1 out of the component and define local component state initialized with data (update all references in render from data to data).

const [data, setData] = useState(data1);

Similar approach as adding a new tab, get the new data name and title. Here we call setData and again use a functional state update, but this time we'll map the existing state to a new array. When the array index matches the active tab index this is the data object we need to updated. Spread its myData into a new array and append the new data object. If index isn't a match then just return the element.

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))
  }
};

  1. Suppose I have 3 tabs (data) so when page loads the first tab data I want to show, but it is not showing up I need to click there only it is showing up.

Issue here is caused by keeping a separate nestedData state object that is only ever updated when a tab is clicked. When a new element is added to the active tab's myData array nestedData isn't updated. Solution here is to simply render the nested data directly in the UI.

Update the tab's onClick handler to simply set the active menu (index).

onClick={() => setactive_menu(index)}

Render the myData directly from the new data state.

data[active_menu].myData.map((li, index) => (...

  1. If the data is null then I can create up to 4 tabs this also I a=want some Idea to do it.

Conditionally rendering the ADD button will control this.

{data.length < 4 && <button onClick={addNewTab}>ADD</button>}

Full Code

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>
  );
}

这篇关于如何在全局标签内创建动态元素的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆