Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/reactjs/23.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Reactjs React属性是空对象,而不是预期的数组_Reactjs_Typescript_Office Ui Fabric - Fatal编程技术网

Reactjs React属性是空对象,而不是预期的数组

Reactjs React属性是空对象,而不是预期的数组,reactjs,typescript,office-ui-fabric,Reactjs,Typescript,Office Ui Fabric,我正试图从Office UI Fabirc控制库中实现一个GroupedList,我离演示代码不远。出于某种原因,当将items数组传递到我通过props(TimeDisplay)构建的函数组件中时,我丢失了列表。我为itemsArray参数获取了一个空Javascript对象,而不是在调用“Home”组件中设置的伪数组。为什么我不去拿我的小阵列?我猜这只是我错过了一些关于React工作方式的东西,但我希望能有任何见解 相关代码 Home.tsx import React, { Componen

我正试图从Office UI Fabirc控制库中实现一个
GroupedList
,我离演示代码不远。出于某种原因,当将items数组传递到我通过props(TimeDisplay)构建的函数组件中时,我丢失了列表。我为
itemsArray
参数获取了一个空Javascript对象,而不是在调用“Home”组件中设置的伪数组。为什么我不去拿我的小阵列?我猜这只是我错过了一些关于React工作方式的东西,但我希望能有任何见解

相关代码

Home.tsx

import React, { Component } from 'react';
import { TimeSubmitter } from './TimeSubmitter'
import { TimeDisplay, TimeEntry } from './TimeDisplay'

type HomeProps = {

}

export class Home extends Component<HomeProps> {
  static displayName = Home.name;
  private items: TimeEntry[] = new Array<TimeEntry>();

  constructor(props: HomeProps){
    super(props);
    this.items.push(
      {
        client: "Apple",
        hours: 1,
        timeCode: "MD",
        loggedDate: new Date()
    });
  }

  render () {
    return (
      <div>
        <TimeDisplay title="Time Logged this Period" items={this.items} />
      </div>
    );
  }
}
import React,{Component}来自'React';
从“/TimeSubmitter”导入{TimeSubmitter}
从“/TimeDisplay”导入{TimeDisplay,TimeEntry}
类型HomeProps={
}
导出类Home扩展组件{
静态显示名称=Home.name;
私有项:TimeEntry[]=new Array();
构造器(道具:家庭道具){
超级(道具);
这个。项目。推(
{
客户:“苹果”,
时间:1,,
时间码:“MD”,
loggedDate:新日期()
});
}
渲染(){
返回(
);
}
}
TimeDisplay.tsx

import React, { FunctionComponent, useState } from 'react'; 
import { GroupedList, IGroup } from 'office-ui-fabric-react/lib/GroupedList';
import { IColumn, DetailsRow } from 'office-ui-fabric-react/lib/DetailsList';
import { FocusZone } from 'office-ui-fabric-react/lib/FocusZone';
import { Selection, SelectionMode, SelectionZone } from 'office-ui-fabric-react/lib/Selection';

type TimeDisplayProps = {
    title: string,
    items: TimeEntry[]
  }
export type TimeEntry = {
    client: string,
    hours: number,
    timeCode: string,
    loggedDate: Date
}

const buildGroups = (items: Array<TimeEntry>) => {
    let groups = new Array<IGroup>();
    let hashSet = new Set<string>();
    for (let index = 0; index < items.length; index++) {
        const element = items[index];
        if(!hashSet.has(element.client)){
            groups.push({
                key: element.client,
                name: element.client,
                startIndex: 0,
                count: 10
            });
            hashSet.add(element.client);
        }
      }
      return groups;
    }

const buildColumns = (item: TimeEntry[]) => {
    return (Object.keys(item)
      .map(
        (key: string): IColumn => ({
          key: key,
          name: key,
          fieldName: key,
          minWidth: 300
        })
      ));
}

export const TimeDisplay: FunctionComponent<TimeDisplayProps> = (title, itemsArray) =>{
    const [items, setItems] = useState(itemsArray);
    const [selection, setSelection] = useState(new Selection());
    const [groups, setGroups] = useState(buildGroups(itemsArray));
    const [columns, setColumns] = useState(buildColumns(itemsArray[0]));

    const onRenderCell = (nestingDepth?: number | undefined, item?: any, index?: number | undefined) => {
        if(nestingDepth != undefined && index != undefined){
            return (
                <DetailsRow
                  columns={columns}
                  groupNestingDepth={nestingDepth}
                  item={item}
                  itemIndex={index | 0}
                  selection={selection}
                  selectionMode={SelectionMode.multiple}
                  compact={false}
                />);
        }
    }

    return (        
    <FocusZone>
        <SelectionZone selection={selection} selectionMode={SelectionMode.single}>
          <GroupedList
            items={items}
            onRenderCell={onRenderCell}
            selection={selection}
            selectionMode={SelectionMode.single}
            groups={groups}
          />
        </SelectionZone>
      </FocusZone>);
}
import React,{FunctionComponent,useState}来自'React';
从“office ui fabric react/lib/GroupedList”导入{GroupedList,IGroup};
从“office ui fabric react/lib/DetailsList”导入{IColumn,DetailsRow};
从“office ui fabric react/lib/FocusZone”导入{FocusZone};
从“office ui fabric react/lib/Selection”导入{Selection,SelectionMode,SelectionZone};
类型TimeDisplayProps={
标题:字符串,
项目:时间输入[]
}
导出类型时间项={
客户机:字符串,
小时数:,
时间码:字符串,
日志日期:日期
}
const buildGroups=(项:数组)=>{
设groups=newarray();
设hashSet=newset();
for(让index=0;index{
返回(对象键(项)
.地图(
(键:字符串):IColumn=>({
钥匙:钥匙,
姓名:key,,
字段名:key,
最小宽度:300
})
));
}
导出常量时间显示:FunctionComponent=(标题,itemsArray)=>{
const[items,setItems]=useState(itemsArray);
const[selection,setSelection]=useState(newselection());
const[groups,setGroups]=useState(buildGroups(itemsArray));
const[columns,setColumns]=useState(buildColumns(itemsArray[0]);
const onRenderCell=(嵌套深度?:编号未定义,项目?:任何,索引?:编号未定义)=>{
if(嵌套深度!=未定义和索引!=未定义){
返回(
);
}
}
报税表(
);
}

此项目仅是主组件上的一个属性。更改它不会导致重新渲染Home或传递给它的TimeDisplay组件。您还需要对TimeDisplay中收到的道具进行分解

所以首先,你应该使用状态;在构造函数中,您可以编写如下内容:

import React, { Component } from 'react';
import { TimeSubmitter } from './TimeSubmitter';
import { TimeDisplay, TimeEntry } from './TimeDisplay';

type HomeProps = {};

export class Home extends Component<HomeProps> {
  static displayName = Home.name;
  private items: TimeEntry[] = new Array<TimeEntry>();

  constructor(props: HomeProps) {
    super(props);

    // set initial state with your object inside the items array
    this.state = {
      items: [
        {
          client: 'Apple',
          hours: 1,
          timeCode: 'MD',
          loggedDate: new Date()
        }
      ]
    };
  }

  render() {
    // change this.items to this.state.items
    return (
      <div>
        <TimeDisplay title='Time Logged this Period' items={this.state.items} />
      </div>
    );
  }
}
将在数组上使用forEach方法,如

items.forEach(element => {
  if (!hashSet.has(element.client)) {
    groups.push({
      key: element.client,
      name: element.client,
      startIndex: 0,
      count: 10
    });
    hashSet.add(element.client);
  }

  return groups;
});

希望这一切都有意义

此.items
只是主组件上的一个属性。更改它不会导致重新渲染Home或传递给它的TimeDisplay组件。您还需要对TimeDisplay中收到的道具进行分解

所以首先,你应该使用状态;在构造函数中,您可以编写如下内容:

import React, { Component } from 'react';
import { TimeSubmitter } from './TimeSubmitter';
import { TimeDisplay, TimeEntry } from './TimeDisplay';

type HomeProps = {};

export class Home extends Component<HomeProps> {
  static displayName = Home.name;
  private items: TimeEntry[] = new Array<TimeEntry>();

  constructor(props: HomeProps) {
    super(props);

    // set initial state with your object inside the items array
    this.state = {
      items: [
        {
          client: 'Apple',
          hours: 1,
          timeCode: 'MD',
          loggedDate: new Date()
        }
      ]
    };
  }

  render() {
    // change this.items to this.state.items
    return (
      <div>
        <TimeDisplay title='Time Logged this Period' items={this.state.items} />
      </div>
    );
  }
}
将在数组上使用forEach方法,如

items.forEach(element => {
  if (!hashSet.has(element.client)) {
    groups.push({
      key: element.client,
      name: element.client,
      startIndex: 0,
      count: 10
    });
    hashSet.add(element.client);
  }

  return groups;
});

希望这一切都有意义

您在功能组件的定义中缺少了解构。因此,功能组件获得一个
props
参数作为第一个参数,它包含所有作为对象键的props。如果要在定义中直接分解它们,则需要大括号。现在,功能组件中的
itemsArray
正在引用功能组件获取的第二个参数,这是使用
React.forwardRef(…)
转发的引用

因此,在道具关键点周围用花括号定义功能组件,如下所示:

export const TimeDisplay: FunctionComponent<TimeDisplayProps> = ({title, itemsArray}) =>{
...
export const TimeDisplay:FunctionComponent=({title,itemsArray})=>{
...

您在功能组件的定义中缺少了解构。因此,功能组件获得了一个
props
参数作为第一个参数,该参数包含所有作为对象键的props。如果您想在定义中直接解构它们,则需要大括号。现在,请在y中使用
itemsArray
我们的功能组件引用了功能组件获取的第二个参数,这是使用
React.forwardRef(…)
转发的引用

因此,在道具关键点周围用花括号定义功能组件,如下所示:

export const TimeDisplay: FunctionComponent<TimeDisplayProps> = ({title, itemsArray}) =>{
...
export const TimeDisplay:FunctionComponent=({title,itemsArray})=>{
...

这是有道理的,我并不惊讶这是一件愚蠢的事情。我也同意forEach。我最初是这样做的,但我不断收到抱怨说“items.forEach不是一个函数”所以我把它改成了for循环。不确定它为什么要这样做。我猜在原始代码中,
items
没有初始化为数组(原因在答案中概述),所以当它寻找forEach方法时,它将无法找到它。哈,这是有意义的。我一定会把forEach放回那里!我今晚会测试并接受它