前端面试题详解整理7| 用 react 实现一个列表,可以单选,多选和取消选择 ,实现图片异步加载函数 , 实现虚拟列表(

216 阅读3分钟

快手前端一面

面试官很好,非常亲切,目前遇到的最好的面试官,但是有点奇怪为啥只考三道业务题,最后也忘记问了

1. 用 react 实现一个列表,可以单选,多选和取消选择
2. 实现一个具有单选、多选和取消选择功能的列表可以通过 React 来完成。下面是一个简单的示例,展示了如何实现这些功能:

import React, { useState } from 'react';

function List() {
  // 列表数据
  const initialItems = [
    { id: 1, name: 'Item 1' },
    { id: 2, name: 'Item 2' },
    { id: 3, name: 'Item 3' },
    // Add more items as needed
  ];

  // 状态管理
  const [items, setItems] = useState(initialItems);
  const [selectedItems, setSelectedItems] = useState([]);

  // 单选函数
  const handleSingleSelect = (itemId) => {
    const selectedItem = items.find(item => item.id === itemId);
    setSelectedItems([selectedItem]);
  };

  // 多选函数
  const handleMultiSelect = (itemId) => {
    const selectedItem = items.find(item => item.id === itemId);
    setSelectedItems(prevSelectedItems => [...prevSelectedItems, selectedItem]);
  };

  // 取消选择函数
  const handleDeselect = (itemId) => {
    const updatedSelectedItems = selectedItems.filter(item => item.id !== itemId);
    setSelectedItems(updatedSelectedItems);
  };

  return (
    <div>
      <h2>List</h2>
      <ul>
        {items.map(item => (
          <li key={item.id}>
            <span>{item.name}</span>
            {/* 单选按钮 */}
            <input
              type="radio"
              name="single-select"
              onChange={() => handleSingleSelect(item.id)}
            />
            {/* 多选复选框 */}
            <input
              type="checkbox"
              onChange={() => handleMultiSelect(item.id)}
            />
            {/* 取消选择按钮 */}
            <button onClick={() => handleDeselect(item.id)}>Deselect</button>
          </li>
        ))}
      </ul>
      {/* 显示已选择的项 */}
      <h3>Selected Items</h3>
      <ul>
        {selectedItems.map(item => (
          <li key={item.id}>{item.name}</li>
        ))}
      </ul>
    </div>
  );
}

export default List;

在这个示例中,我们创建了一个 List 组件,其中包含了一个包含项目名称、单选按钮、多选复选框和取消选择按钮的列表。通过使用 useState 钩子来管理列表数据和选中的项目。通过点击单选按钮、多选复选框或取消选择按钮来更新选中项目的状态。

3. 实现图片异步加载函数

在 React 中实现图片异步加载函数可以使用 useEffect 钩子和 new Image() 对象。下面是一个示例:

import React, { useState, useEffect } from 'react';

function AsyncImage({ src, alt }) {
  const [loading, setLoading] = useState(true);
  const [error, setError] = useState(false);

  useEffect(() => {
    const loadImage = () => {
      const img = new Image();
      img.src = src;

      img.onload = () => {
        setLoading(false);
      };

      img.onerror = () => {
        setLoading(false);
        setError(true);
      };
    };

    loadImage();

    // 清理函数
    return () => {
      // 在组件卸载时取消图片加载
    };
  }, [src]); // 依赖于图片的 src

  return (
    <div>
      {loading && <p>Loading...</p>}
      {error && <p>Error loading image.</p>}
      {!loading && !error && <img src={src} alt={alt} />}
    </div>
  );
}

export default AsyncImage;

在这个示例中,我们创建了一个 AsyncImage 组件,它接受 srcalt 作为 props。在组件加载时,我们使用 useEffect 钩子来异步加载图片。当图片加载完成时,我们设置 loading 状态为 false,表示加载完成;当图片加载失败时,我们设置 error 状态为 true。最后,根据 loadingerror 状态来渲染不同的内容。

这个组件在加载图片时会显示 "Loading...",加载完成后显示图片,如果加载失败则显示 "Error loading image."。

3  实现虚拟列表(本来是一个关于 HOC 的题目,但听说我不知道HOC 就换了一道)
虚拟列表是一种用于优化大型列表性能的技术,它只渲染用户当前可见的部分列表项,而不是一次性渲染整个列表。这可以通过计算并动态更新列表项的位置和内容来实现。以下是一个简单的示例实现虚拟列表的 React 组件:

import React, { useState, useEffect } from 'react';

function VirtualList({ height, itemCount, itemHeight, renderItem }) {
  const [scrollTop, setScrollTop] = useState(0);
  const [visibleItems, setVisibleItems] = useState([]);

  useEffect(() => {
    const handleScroll = (e) => {
      setScrollTop(e.target.scrollTop);
    };

    const container = document.getElementById('virtual-list-container');
    container.addEventListener('scroll', handleScroll);

    return () => {
      container.removeEventListener('scroll', handleScroll);
    };
  }, []);

  useEffect(() => {
    const startIndex = Math.floor(scrollTop / itemHeight);
    const endIndex = Math.min(
      startIndex + Math.ceil(height / itemHeight),
      itemCount
    );

    const items = [];
    for (let i = startIndex; i < endIndex; i++) {
      items.push(renderItem(i));
    }
    setVisibleItems(items);
  }, [scrollTop, height, itemCount, itemHeight, renderItem]);

  return (
    <div
      id="virtual-list-container"
      style={{ height: `${height}px`, overflowY: 'auto' }}
    >
      <div style={{ height: `${itemCount * itemHeight}px`, position: 'relative' }}>
        {visibleItems.map((item, index) => (
          <div key={index} style={{ position: 'absolute', top: `${index * itemHeight}px`, width: '100%' }}>
            {item}
          </div>
        ))}
      </div>
    </div>
  );
}

export default VirtualList;

在这个示例中,VirtualList 组件接受 height(可见区域的高度)、itemCount(列表项总数)、itemHeight(每个列表项的高度)和 renderItem(渲染列表项的函数)作为 props。它使用 scrollTop 状态来跟踪用户滚动的位置,并根据可见区域的位置和大小计算出当前可见的列表项,并动态渲染。通过将列表项的 position 设置为 absolute,它们在滚动时会保持在正确的位置。

面试官给我评价就是,“vue” 风有点严重(其实 react  也写过很多,最近手生忘咋写了),然后也说了句没想到我三道题这么快完成(30多分钟吧),最后就是闲聊时间,介绍了公司的业务,看我学了 rust,也说了 rust 在公司里的应用场景,最后反问

作者:Plumbiu
链接:www.nowcoder.com/feed/main/d…
来源:牛客网