Cómo actualizar textContent de div usando una referencia en reaccionar y evitar render (para el rendimiento), cuando los cambios dependen de los apoyos?

votos
0

Tengo un componente llamado Parentde que en componentDidMountabre una conexión WebSocket y continuamente recibe datos cada 100 ms. Cuando recibe estos datos, se utiliza setStatepara actualizar el estado con los nuevos datos, lo cual es una matriz de objetos. Los objetos representan filas de una tabla, que tiene las llaves para cada columna.

En el método render, Parenthace que una Childpara cada objeto en la matriz, pasando el objeto como prop.

La Childhace que las células (cada célula es un div) para cada tecla en el pasado en prop objeto. Sin embargo, por razones de rendimiento, mi suposición es que es más rápido para el Childpara generar una referencia para cada celda, y cuando los nuevos apoyos vienen en, simplemente para cambiar el textContentde cada célula con el nuevo valor.

shouldComponentUpdatePor lo tanto, devuelve false en el Child, por lo que no Reaccionar renders suceda después de la primera representación. Los cambios ocurren en todo componentWillReceiveProps. El problema es que no debemos utilizar este método de ciclo de vida más. Cuál es la alternativa en esta lista?

Código

// 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>
    );
  }
}
Publicado el 09/10/2019 a las 18:59
fuente por usuario
En otros idiomas...                            

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