在Reactionic / react中动态创建具有独立状态/数据的UI元素的正确方法是什么

如何解决在Reactionic / react中动态创建具有独立状态/数据的UI元素的正确方法是什么

我不是前端开发人员,但我对JavaScript足够了解,可以解决此问题。但是,我最近开始与React框架结合使用Ionic。我是Ionic / React的初学者,在遇到这个问题之前,我发现它很有趣。

我正在开发的应用程序很简单。我正在通过服务器从Websockets(近)实时接收值,我想在UI中显示它们。为此,我在用户界面中有ItemSliding or SlidingComponents,可以在其中向右滑动以通过Websocket订阅(向服务器发送“获取消息”事件并开始使用消息/值),也可以向右滑动以退订并停止获取消息,或者我可以单击以从用户界面中删除ItemSliding。

由于我希望动态创建ItemSlidings或SlidingComponents,因此我搜索并发现可以循环浏览UI中的列表并即时创建元素,这是一个很棒的功能,我喜欢它,所以我m使用以下代码

import React,{ useEffect,useState } from 'react';
const [selectedTopics,setSelectedTopics] = useState([]);  
.
.
. 
{selectedTopics.map((topic: any,idx: number) =>
        < Slider key={idx}  // I tried uuid here but it didn't work
          topic={topic}
          socket={socket}
          selectedTopics={selectedTopics}
          setSelectedTopics={(topics: any) => setSelectedTopics(topics)}

        />)
      }

我没有显示所有代码库,因为我已经有数千行代码,因此我将其保持简单。如您所见,我遍历selectedTopics列表,并为该列表中的每个主题创建一个Slider(ItemSliding组件)。滑块是我正在创建的自定义react组件,在这里我将发布该结构的一个最小示例:

import React,{ useState,useRef,useEffect} from 'react';
import { IonItemSliding,IonItemOptions,IonItemOption,IonItem,IonLabel,IonNote,IonIcon,IonSpinner } from '@ionic/react';
import { trash,ellipse } from 'ionicons/icons';



const Slider: React.FC<{
  socket: SocketIOClient.socket;
  topic: any;
  selectedTopics: any;
  setSelectedTopics: any;
}> = (props) => {

  const [realTimeValue,setRealTimeValue] = useState<string>("");
  const [loading,setLoading] = useState<boolean>(false);
  const [subscribed,setSubscribed] = useState<boolean>(false);

  
  const onSubscribe = (topic: any) => {
    
    props.socket.on("onSubscribe",(data: any) => {

      try {
        const name = data.Name;
        const payload = data.Value;

        console.log(`received response with name: ${name} and payload: ${payload}`);
      if (topic.name === name) {
        console.log(`topic received= ${name} correspond to tpic name = ${topic.name}`);
        setSubscribed(true);
        setRealTimeValue(payload);
        setLoading(false);

      }
      else {

        console.log(`received topic = ${name} but current was ${topic.name} `);
      }
      }
      catch(err) {
        console.log("error",err);
      }
      

    });
  }

  const subscribe = (topic: any) => {

    const req = {
          subscribe: topic.Topic,}
     
    props.socket.emit('subscribe',req);
    setLoading(true);
    onSubscribe(topic);


  }

  const unsubscribe = (topic: any) => {

    const req = {
          unsubscribe: topic.Topic,}

    props.socket.emit('unsubscribe',req);
    setSubscribed(false);
    setRealTimeValue("");
    setLoading(false);
  }

  const deletetopic = (topic: any) => {
    console.log('delete this topic : ' + topic.name);
    unsubscribe(topic);
    const newSelectedTopics = props.selectedTopics.filter((topicObj: any) => topic.name !== topicObj.Name);
    props.setSelectedTopics(newSelectedTopics);

  }
  
  return (
    <IonItemSliding>
      <IonItemOptions onIonSwipe={() => subscribe(props.topic)} side="start">

      </IonItemOptions>

      <IonItem color={"light"}>
        <IonLabel>
        <IonIcon className="subscription-icon"
            color={loading ? "warning" : subscribed ? "success" : "danger"}
            icon={ellipse}
          >
          </IonIcon>
          {props.topic.name}
        </IonLabel>

        <IonNote slot="end" color="dark">
          {subscribed ? realTimeValue : loading ? <IonSpinner name="circles" /> : ""}
        </IonNote>
      </IonItem>

      <IonItemOptions onIonSwipe={() => unsubscribe(props.topic)} side="end">
        <IonItemOption color="danger" onClick={() => { deletetopic(props.topic) }}>
          <IonIcon icon={trash}></IonIcon>
        </IonItemOption>
      </IonItemOptions>
    </IonItemSliding>

  );
};

export default Slider;

这是我用于滑块的代码。因此,我遍历了selectedTopics列表,并为该列表中的每个主题创建了一个Slider。如您所见,我将套接字作为道具传递,因为我想仅使用应用程序的一个全局套接字连接来发出事件并订阅来自服务器的响应。

正如我所说,问题是,有时我会收到值,并在console.log(在浏览器中)看到值来了,但它们未在UI中显示。其他时候显示值,但它们不在我想要的位置。例如,我收到topic1的值(应该是第一个Slider),但是在第二个Slider中显示了该值,这没有意义,因为我正在循环并为列表中的每个主题创建唯一的Slider,对?

我试图分配一个UUID而不是索引作为键,但是它没有用(实际上更糟)。然后,我尝试使用useEffect,但令人不寒而栗,它也不起作用。

在这里做错什么了吗?我的方法或算法错误吗?我不确定在这种情况下的思维方式,因为我通常是React&Frontend的初学者。每个滑块应该具有自己的主题状态,并且根本不使用props.topic吗?我应该在这里使用useEffect吗?

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐


Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其他元素将获得点击?
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。)
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbcDriver发生异常。为什么?
这是用Java进行XML解析的最佳库。
Java的PriorityQueue的内置迭代器不会以任何特定顺序遍历数据结构。为什么?
如何在Java中聆听按键时移动图像。
Java“Program to an interface”。这是什么意思?
Java在半透明框架/面板/组件上重新绘画。
Java“ Class.forName()”和“ Class.forName()。newInstance()”之间有什么区别?
在此环境中不提供编译器。也许是在JRE而不是JDK上运行?
Java用相同的方法在一个类中实现两个接口。哪种接口方法被覆盖?
Java 什么是Runtime.getRuntime()。totalMemory()和freeMemory()?
java.library.path中的java.lang.UnsatisfiedLinkError否*****。dll
JavaFX“位置是必需的。” 即使在同一包装中
Java 导入两个具有相同名称的类。怎么处理?
Java 是否应该在HttpServletResponse.getOutputStream()/。getWriter()上调用.close()?
Java RegEx元字符(。)和普通点?