【问题标题】:React add table cell flash animation on useState changeReact 在 useState 更改时添加表格单元格 flash 动画
【发布时间】:2020-05-17 02:57:56
【问题描述】:

我正在使用 React 构建一个动态表。

应用程序使用来自 websocket 的数据,每次收到新消息时,我都会更新包含数据表的状态。我想在包含已更改数据的单元格中添加一个闪烁的闪光灯,但由于整个状态正在更新,因此整个表重新呈现明显。

我的组件:

  const [contracts, setContracts] = useState([]);
  const [isContracts, setIsContracts] = useState(false);
  const [isSocket, setIsSocket] = useState(false);

  useEffect(() => {
    const fetchContracts = async () => {
      try {
        // ..PULLING DATA FROM THE SERVER
        // 
        setContracts((prevContracts) => [...prevContracts, ...grouped]);

        setIsContracts(true);
      } catch (err) {
        console.error(err);
      }
    };

    // Avoid multiple XHR connections
    if (!isContracts) {
      fetchContracts();
    }
  }, [setContracts]);


  const updateQuote = (data) => {
    const parsed = JSON.parse(data);
    if (parsed.type === 'book_top') {
      const { contract_id, ask, bid } = parsed;

      const newContracts = contracts.map((x) => {
        if (x.put && x.call) {
          if (x.put.id === contract_id) {
            x.put.ask = ask;
            x.put.bid = bid;
          } else if (x.call.id === contract_id) {
            x.call.ask = ask;
            x.call.bid = bid;
          }
        }
        return x;
      });


     // THIS IS WHERE RELEVANTE STATE UPDATE HAPPENS
      setContracts(newContracts);
    }
  };


// this is where the data is being pulled from WS 
if (!isSocket) {
      socket = io('http://localhost:4000');
      setIsSocket(true);
      socket.on('connect', () => {
        console.log('connected to socket');
      });
      socket.on('quotes', (data) => {
        console.log(data);
        updateQuote(data);
      });
    }

return (
    <div>
      {contracts && (
        <ResponsiveTable data={contracts} />
      )}
    </div>

我的餐桌代码:

const ResponsiveTable = ({ data }) => {
  return (
    <div className='table-wrapper'>
      <table className='fl-table'>
        <thead>
          <tr>
            <th className={'blue-bg'}>OI</th>
            <th className={'blue-bg'}>Bid</th>
            <th className={'blue-bg'}>Ask</th>
            <th className={'purple-bg'}>Strike</th>
            <th className={'green-bg'}>Bid</th>
            <th className={'green-bg'}>Ask</th>
            <th className={'green-bg'}>OI</th>
          </tr>
        </thead>
        <tbody>
          {data.map((option) => {
            if (item && item.put) {
              const { call, data_expires, put, strike_price } = item;
              return (
                <tr key={uuidv4()}>
                  <td>{call.open_interest}</td>
                  <td>{call.bid}</td>
                  <td>{call.ask}</td>
                  <td>{strike_price}</td>
                  <td>{put.bid}</td>
                  <td>{put.ask}</td>
                  <td>{put.open_interest}</td>
                </tr>
              );
            }
          })}
        </tbody>
      </table>
    </div>
  );
};

我的眨眼动画(这应该在文本更新的单元格中触发)

td {
  -moz-transition: all 0.5s ease-in;
  -o-transition: all 0.5s ease-in;
  -webkit-transition: all 0.5s ease-in;
  transition: all 0.5s ease-in;
  color: black;
  padding: 20px;
  animation: blinker 1s linear 2 !important;
}

@keyframes blinker {
  50% {
    opacity: 0;
  }
}

我不确定最好的解决方案是什么。理想情况下,应将 CSS 类添加到包含具有新内容的元素的 td 项中。

【问题讨论】:

    标签: javascript html reactjs react-hooks


    【解决方案1】:

    问题是你用错了key:

    return (
            <tr key={uuidv4()}>
               <td>{call.open_interest}</td>
    

    这样每次重新渲染组件时,都会生成一个新的键,因此 React 将始终创建新的 tr 元素,而不是更新当前的 tr 元素。这样你的整个表格就被完全重新渲染了。 一种解决方案是使用数据中的 id:

    return (
                <tr key={item.id}>
                   <td>{call.open_interest}</td>
    

    【讨论】:

    • 感谢刚刚解决了这个问题。你会怎么做眨眼的事情?
    • @greatTeacherOnizuka: 你可以为 ResponsiveTable 创建新的 prop 让它知道哪个单元格需要闪烁: 在 ResponsiveTable 我们可以有条件地为更新的单元格应用闪烁类 ${item.id}_open_interest ? “闪烁”:“”}>{call.open_interest}
    猜你喜欢
    • 1970-01-01
    • 2021-09-11
    • 2014-08-15
    • 2011-04-08
    • 1970-01-01
    • 2014-04-30
    • 2023-03-26
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多