Массив объектов не определен при рендеринге страницы. Потенциальная путаница при повторном рендеринге страниц

#javascript #arrays #reactjs #react-native

#javascript #массивы #reactjs #react-native

Вопрос:

Я новичок в React, и в настоящее время я борюсь с этой концепцией, для которой, похоже, не могу найти исправления. У меня есть компоненты, родительский и дочерний. Родительский компонент передает данные дочернему компоненту через props. Я вижу, что данные передаются при первом рендеринге страницы, но я заметил в консоли, что при втором и третьем рендеринге страницы массив возвращается как неопределенный. Я не понимаю, почему массив не определен, это потому, что я не устанавливаю состояние в дочернем компоненте?

Код дочернего компонента:

 export class NumOfDaysTable extends Component {
    static displayName = NumOfDaysTable.name;

    constructor(props) {
        super(props);
        this.state = {
            headers: [["Number", "Type", "Customer Name", "Customer", "Code", "Amount", "Date Submitted", "Notes", "Status"]],
            data: props.dataParentToChild
        };

    }
    render() {
        const { data } = this.state;
        console.log( data)
        const { headers } = this.state;
        
        return (
            <div>
                <h4 > {this.props.title} </h4>
                <Container>
                    <Table size="sm">
                        <thead>
                            {headers.map((headerData) => (
                                <tr>
                                    {headerData.map((headerRecord) => (
                                        <th>{headerRecord}</th>
                                        
                                    
                                    ))}
                                    </tr>
                                    ))}
                        </thead>

                        <tbody>
                            
                            {data.map((item) => ( 

                                
                                <tr>
                                     {item.map((record) => ( 
                                       <td>{record} </td> 
                                   ))}               
                                </tr>
                             ))} 

                        </tbody>

                    </Table>
                </Container>

            </div>
        );
    }
}


export default NumOfDaysTable; ```
 

Комментарии:

1. Вы не хотите переназначать свой реквизит в локализованное состояние, вероятно, это и есть причина вашей ошибки. Проверьте reactjs.org/docs/state-and-lifecycle.html

2. Я очень смущен, теперь, когда я начал, так что, возможно, это прогресс, ха-ха. Согласно документации и, если я правильно понимаю, я хочу использовать componentDidMount для установки данных, а затем отобразить их в моем рендеринге. Однако, когда я добавляю это, моя ошибка остается прежней. Я все еще получаю неопределенную ошибку.

3. эй, я понимаю, не беспокойся. Однако, чтобы внести ясность, не пытайтесь присваивать реквизиты локальному состоянию, будь то в constructor или componentDidMount . Реквизит должен быть просто «принят» дочерним компонентом. Возможно, данные undefined изначально, поэтому вам может потребоваться добавить защиту, прежде чем пытаться получить доступ к этим данным.

Ответ №1:

Не переназначайте свой реквизит своему состоянию, вы потеряете реактивность при обновлении данных.

     constructor(props) {
        super(props);
        this.state = {
            headers: [["Number", "Type", "Customer Name", "Customer", "Code", "Amount", "Date Submitted", "Notes", "Status"]],
            // data: props.dataParentToChild --- REMOVE THIS LINE
        };

    }
 

А затем настройте свою функцию рендеринга

     render() {
        const  data  = this.props.dataParentToChild;
        console.log( data)
        const { headers } = this.state;
// ...REST OF CODE
 

Ответ №2:

Причина в основном в порядке, в котором выполняется наш компонент React. Только для начального рендеринга нет данных, и нам нужно обработать это в нашем проекте.

Вам нужно отобразить свой компонент, установив условие, которое Only when data is passed to the Component render it. я использовал {data amp;amp; (<div>...</div>)} в своем дочернем компоненте:

Вот рабочее решение:

Родительский компонент: : Передача реквизитов

 import React from "react";
import NumOfDaysTable from "./StackOverflow";

const dataParentToChild = [
  {
    userId: 1,
    id: 1,
    title:
      "sunt aut facere repellat provident occaecati excepturi optio reprehenderit",
    body:
      "quia et suscipitnsuscipit recusandae consequuntur expedita et cumnreprehenderit molestiae ut ut quas totamnnostrum rerum est autem sunt rem eveniet architecto",
  },
  {
    userId: 1,
    id: 2,
    title: "qui est esse",
    body:
      "est rerum tempore vitaensequi sint nihil reprehenderit dolor beatae ea dolores nequenfugiat blanditiis voluptate porro vel nihil molestiae ut reiciendisnqui aperiam non debitis possimus qui neque nisi nulla",
  },
  {
    userId: 1,
    id: 3,
    title: "ea molestias quasi exercitationem repellat qui ipsa sit aut",
    body:
      "et iusto sed quo iurenvoluptatem occaecati omnis eligendi aut adnvoluptatem doloribus vel accusantium quis pariaturnmolestiae porro eius odio et labore et velit aut",
  },
  {
    userId: 1,
    id: 4,
    title: "eum et est occaecati",
    body:
      "ullam et saepe reiciendis voluptatem adipiscinsit amet autem assumenda provident rerum culpanquis hic commodi nesciunt rem tenetur doloremque ipsam iurenquis sunt voluptatem rerum illo velit",
  },
  {
    userId: 1,
    id: 5,
    title: "nesciunt quas odio",
    body:
      "repudiandae veniam quaerat sunt sednalias aut fugiat sit autem sed estnvoluptatem omnis possimus esse voluptatibus quisnest aut tenetur dolor neque",
  },
];
const Home = () => {
  return (
    <div>
      <h1>Home Page</h1>
      <NumOfDaysTable
        title="Reality Check"
        dataParentToChild={dataParentToChild}
      />
    </div>
  );
};

export default Home;
 

Дочерний компонент :

 import React, { Component } from "react";
export class NumOfDaysTable extends Component {
  //   static displayName = NumOfDaysTable.name;

  constructor(props) {
    super(props);
    this.state = {
      headers: [
        [
          "Number",
          "Type",
          "Customer Name",
          "Customer",
          "Code",
          "Amount",
          "Date Submitted",
          "Notes",
          "Status",
        ],
      ],
      data: props.dataParentToChild,
    };
  }
  render() {
    const { data } = this.state;
    const { headers } = this.state;
    console.log("Data Coming from the prop");
    console.log(data);
    return (
      <div>
        {data amp;amp; (
          <>
            <h4> {this.props.title} </h4>
            <section>
              <table size="sm">
                <thead>
                  {headers.map((headerData) => (
                    <tr>
                      {headerData.map((headerRecord, index) => (
                        <th key={index}>{headerRecord}</th>
                      ))}
                    </tr>
                  ))}
                </thead>

                <tbody>
                  {data.map((item) => (
                    <tr key={item.id}>
                      <td>{item.title} </td>
                    </tr>
                  ))}
                </tbody>
              </table>
            </section>
          </>
        )}
      </div>
    );
  }
}

export default NumOfDaysTable;
 

Ответ №3:

Вы должны определить данные в своем родительском компоненте.

Посмотрите в CodeSandbox

 // Parent component example

import React from "react";
import "./styles.css";

import NumOfDaysTable from "./NumOfDaysTable.js";

export default function App() {
  return (
    <NumOfDaysTable
      dataParentToChild={[
        [1,"Type 1","Customer 1","Name 1","Code 1","Amount 1","Date 1","Notes 1","Status 1"],
        [2,"Type 2","Customer 2","Name 2","Code 2","Amount 2","Date 2","Notes 2","Status 2"],
        [3,"Type 3","Customer 3","Name 3","Code 3","Amount 3","Date 3","Notes 3","Status 3"],
        [4,"Type 4","Customer 4","Name 4","Code 4","Amount 4","Date 4","Notes 4","Status 4"]
      ]}
    />
  );
}
 

И не забывайте уникальные ключи для вашего компонента при итерации!

 // NumOfDaysTable.js
// code...

  render() {
    const { data } = this.state;
    console.log(data);
    const { headers } = this.state;

    return (
      <div>
        <h4> {this.props.title} </h4>
        <div>
          <table size="sm">
            <thead>
              {headers.map((headerData, id) => (
                <tr key={"headerData"   id}>
                  {headerData.map((headerRecord, id) => (
                    <th key={"headerRecord"   id}>{headerRecord}</th>
                  ))}
                </tr>
              ))}
            </thead>
            <tbody>
              {data.map((item, id) => (
                <tr key={"item"   id}>
                  {item.map((record, id) => (
                    <td key={"record"   id}>{record}</td>
                  ))}
                </tr>
              ))}
            </tbody>
          </table>
        </div>
      </div>
    );
  }

// code...