React 16.8 hooks =>如何正确地将元素数组注入DOM

时间:2019-04-24 10:37:26

标签: reactjs react-hooks

我正在使用React的钩子(版本16.8.6)注入具有各自索引+值+ onClick = {}的按钮数组。

简洁的基本代码

function App() {
   const [rooms, setRoomArray] = useState([]);
   const roomArray = [
     'room1',
   'room2',
   'room3',
   'room4',
  ];

   const handleNewMessage = (room) => {
       setRoomArray(roomArray);
       roomSpawner(rooms);
   };

   const test = () =>{
       console.log('test here');
   }

   const roomSpawner = (rooms) =>{
        return rooms.map((value,index) => (
            <button onClick={test()} key={index}>{value}</button>
        ));
};

一切正常,并且显示正常,但是通过控制台日志记录,我发现我的控制台为going into a loop,存在一个循环,我正在尝试了解:

  1. 这是一个循环还是它的常规轮询/响应行为?
  2. 就性能而言,这是否“昂贵”?
  3. 在轮询远程服务器的套接字连接中插入test()有意义吗?
  4. 我滥用结构吗?如果是这样,请告诉我如何正确注入元素数组。

1 个答案:

答案 0 :(得分:1)

问题1:这是一个循环还是它的常规轮询/反应行为?

答案:正如评论者所指出的,该循环是由onClick={test()}引起的。 onClick道具期望函数(而不是函数调用)作为事件处理程序附加。您可以执行以下操作:

const test = (index) =>{
  console.log('I was called for room number: ' + index);
}

const roomSpawner = (rooms) =>{
  return rooms.map((value,index) => (
    <button onClick={() => test(index)} key={index}>{value}</button>
  ));

第二季度:就性能而言,这是否“昂贵”?

一点也不。这是一个完美的有效React实现。

问题3:将轮询远程服务器的套接字连接插入test()有意义吗?

我不这么认为。您应该将套接字连接插入useEffect()挂钩中以在安装时进行连接。像这样:

// INSIDE YOUR COMPONENT

useEffect(()=> {
  // CONNECT TO SOCKET
  // ON SOCKET MESSAGES, UPDATE SOME STATE WITH THE NEW ROOMS AND COMPONEN WILL RE-RENDER
  return () => {
    // DISCONNECT FROM SOCKET
  }
},[]); // WITH THIS EMPTY ARRAY, THIS EFFECT WILL RUN ON 1ST RENDER, AND IT WILL DISCONECT FROM YOUR SOCKET WHEN IT GETS DISMOUNTED

React DOCS on useEffect()

问题4:我是否滥用该构造?如果是这样,请告诉我如何正确注入元素数组。

我认为你很好。使用useState()将房间阵列保持在状态变量中,并使用stateWithArrayOfRooms.map()生成组件(按钮或其他任何东西)。像

// INSIDE YOUR COMPONENT

const [roomsArray, setRoomsArray] = useState([]);

useEffect(()=>{
  // CONNECT TO YOUR SOCKET AND UPDATE roomsArray with new messages.
  // setRoomsArray('newRoomsArray from socket');
  return () => {
    // DISCONNECT FROM SOCKET
  }
},[]);

const roomItems = roomsArray.map((item, index) => 
  <RoomComponent key={index or some other unique id} onClick={()=>test(index)}/>
);

return (
  <RoomsContainer>
    {roomItems}
  </RoomsContainer>
);