Wie textcontent von div mit einem ref in Reagieren und die Vermeidung von render (für Leistung), zu aktualisieren, wenn die Updates auf die Stützen ab?

stimmen
0

Ich habe eine Komponente genannt , Parentdass in componentDidMountöffnet eine websocket Verbindung und empfängt kontinuierlich alle 100ms Daten. Wenn es diese Daten empfängt, verwendet es setStateZustand mit den neuen Daten zu aktualisieren, die eine Anordnung von Objekten. Die Objekte repräsentieren Zeilen in einer Tabelle, Schlüssel für jede Spalte aufweist.

Bei dem Verfahren macht, Parentmacht eine Childfür jedes Objekt in dem Array, in dem Objekt als prop geben.

Die Childrendert Zellen (Jede Zelle ist ein div) für jede Taste in der in Objekt prop geben. Jedoch aus Leistungsgründen, meine Vermutung ist , dass es schneller ist für die Childeinen ref für jede Zelle zu erzeugen, und wenn neue Requisiten in kommen, nur das zu ändern textContentjeder Zelle mit dem neuen Wert.

shouldComponentUpdatedeshalb gibt false zurück , in der Child, so dass keine React macht geschehen , nachdem die anfänglichen machen. Die Updates alle passieren in componentWillReceiveProps. Das Problem ist , dass wir nicht mehr diese Lebenszyklus - Methode verwenden sollen. Was die Alternative hier?

Code

// Parent
import React from 'react';
import { connectViaWebsocket } from '../../api/connectViaWebsocket';
import { LoadingSpinner } from '../spinners/LoadingSpinner';
import styled from 'react-emotion';

interface ParentData {
  col1: number;
  col2: number;
  col3: number;
  col4: number;
}

interface State {
  data: ParentData[];
  isConnected: boolean;
}

export class Parent extends React.Component<{}, State> {
  constructor(props: {}) {
    super(props);
    this.state = { data: [], isConnected: false };
  }

  public componentDidMount() {
    connectViaWebsocket(data => this.setState({ isConnected: true, data: JSON.parse(data) }));
  }

  public render() {
    return this.state.isConnected ? (
      <Container>
        {this.state.data.map((row, index) => (
          <Child
            key={index}
            col1={row.col1}
            col2={row.col2}
            col3={row.col3}
            col4={row.col4}
          />
        ))}
      </Container>
    ) : (
      <LoadingSpinner showSpinner={false} text={'Connecting...'} />
    );
  }
}

const Container = styled('div')`
  background-color: white;
  height: 100%;
  font-size: 0.8em;
`;
import React from 'react';
import styled from 'react-emotion';

interface Props {
  col1: number;
  col2: number;
  col3: number;
  col4: number;
}

type ChildCellRefs = { [key: string]: React.RefObject<HTMLElement> };
export class Child extends React.Component<Props> {
  private cellRefs: ChildCellRefs = {
    col1: React.createRef<HTMLDivElement>(),
    col2: React.createRef<HTMLDivElement>(),
    col3: React.createRef<HTMLDivElement>(),
    col4: React.createRef<HTMLDivElement>(),
  };

  public componentDidMount() {
    this.update();
  }

  public shouldComponentUpdate() {
    return false;
  }

  public componentWillReceiveProps(nextProps {
    this.update(nextProps);
  }

  private update(data: Props) {
    this.fillData(data);
  }

  private fillData(data: Props) {
    Object.keys(this.cellRefs).forEach(key => {
      const dataKey = key;
      const cell = this.cellRefs[dataKey].current;
      const dataValue = `${data[dataKey]}`;
      if (cell) {
        if (cell.textContent !== dataValue) {
          cell.textContent = dataValue;
        }
      }
    });
  }

  public render() {
    return (
      <Row>
        <DataCellsContainer>
          <DataCell innerRef={this.cellRefs.col1} />
          <DataCell innerRef={this.cellRefs.col2} />
          <DataCell innerRef={this.cellRefs.col3} />
          <DataCell innerRef={this.cellRefs.col4} />
        </DataCellsContainer>
      </Row>
    );
  }
}
Veröffentlicht am 09/10/2019 um 18:59
quelle vom benutzer
In anderen Sprachen...                            

Cookies help us deliver our services. By using our services, you agree to our use of cookies. Learn more