简体   繁体   English

使用 jsx 动态替换元素

[英]Dynamically replace elements using jsx

I'm having an array data.info that is being updated over time and I'm trying to replace placeholder rendered elements with another.我有一个数组data.info随着时间的推移而更新,我正在尝试用另一个替换占位符呈现的元素。 So by default app.js looks like this所以默认情况下app.js看起来像这样

return (
    <Fragment>
        {data.info.map((index) => {
            return <Typography key={index} variant="h6" className={classes.title}>Demo</Typography>
                })}
    </Fragment>
)

Also I have a hook with async function to subscribed to data.info.length .另外,我有一个带有异步 function 的钩子订阅data.info.length

useEffect(
    () => {
        if (!initialRender.current) {
            if (data.info.length!==0) {
            for (let i = data.info.length-iScrollAmount+1 ; i < data.info.length+1; i++) {
                firstAsync(i)
            }
        }

        } else {
            initialRender.current = false
        }
    },
    [data.info.length]
)

async function firstAsync(id) {
    let promise = new Promise(() => {
            setTimeout(() => console.log(document.getElementById(id)), 500)
    });
    }

With document.getElementById() and id I can get to every element that was rendered and change it.使用document.getElementById()id我可以访问每个渲染的元素并对其进行更改。 And here goes the problems.这就是问题所在。

  1. I'm using material-ui so I can't get to <Typography/> because it is transformed into <h6/> .我正在使用material-ui所以我无法进入<Typography/>因为它已转换为<h6/> Probably that is not a problem since I need to replace contents, so I can find parent element and remove all children.可能这不是问题,因为我需要替换内容,所以我可以找到parent元素并删除所有子元素。 Is that way correct?这种方式正确吗?

  2. After I delete children how do I add content using jsx ?删除子项后,如何使用jsx添加内容? What I mean is that in async function I'll get an array that I want to use in new element <NewCard/> to dynamically put into <Fragment/> .我的意思是,在异步 function 中,我会得到一个数组,我想在新元素<NewCard/>中使用它来动态放入<Fragment/> Yet I did not find any example how to do that.但是我没有找到任何示例如何做到这一点。

It is not a good practice to change DOM Nodes directly in React, and you need to let React do the rendering for you and you just tell react what to do.直接在 React 中更改DOM Nodes不是一个好习惯,您需要让 React 为您进行渲染,您只需告诉 react 做什么。

in your case you need to define a React State for your data and set your state inside your firstAsync function and then use your state to render whatever html element or React component which you want in your case you need to define a React State for your data and set your state inside your firstAsync function and then use your state to render whatever html element or React component which you want

React does not encourage the practice of manipulating the HTML DOM nodes directly. React 不鼓励直接操作 HTML DOM 节点的做法。

Basically you need to see 2 things.基本上你需要看两件事。

  1. State which is a special variable whose value is retained on subsequent refresh. State这是一个特殊变量,其值在后续刷新时保留。 Change in reference in this variable will trigger component and its children a refresh/re-render.此变量中的引用更改将触发组件及其子项刷新/重新渲染。
  2. Props which is passed to every Component and is read only.传递给每个ComponentProps并且是只读的。 Changing in props causes refresh of component by default.默认情况下,更改 props 会导致组件刷新。

In your example, based on data.info you want to render Typography component.在您的示例中,基于data.info您要呈现Typography组件。

Solution解决方案

  1. First thing is your map function is incorrect.首先是您的 map function 不正确。 First parameter of map function is item of list and second is index. map function 的第一个参数是列表项,第二个是索引。 If you are not sure if info will always be present in data , you may want to have a null check as well.如果您不确定info是否始终存在于data中,您可能还需要检查 null。

{(data.info || []).map((info, index) => { return <Typography key={index} variant="h6" className={classes.title}>{info.text}</Typography> })}

  1. You should be passing info from map to Typography component.您应该将infomap传递给Typography组件。 Or use info value in content of Typography as shown above.或者在Typography内容中使用info值,如上所示。
  2. Update data.info and Typography will update automatically.更新data.infoTypography将自动更新。 For this, please make sure, data.info is a component state and not a plain variable.为此,请确保data.info是一个组件 state 而不是普通变量。 Something like就像是

const [data, setData] = React.useState({});

And when you have value of data (assuming from API), then当您拥有data价值时(假设来自 API),那么

setData(responseApi);

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

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