admin管理员组

文章数量:1399466

A developer gave me an api specification which is a List that can accept an array of objects using the ListItem shape described below; this will be transformed into a set of rendered List.Item ponents.

API

The List ponent accepts the following props:

  • items (ListItem[]): Required. This array should contain one or more JSX elements, or one or more ListItem objects (see below for details).
  • searchable (string[]): Optional. Accepts an array of strings which match the names of ListItem properties. If present, a localized freeform search box is rendered above the list, and entry within that field will filter the internal data using the provided keys as a guide.

Schemas


ListItem

ListItem is the object schema for an individual item in the list.

{
    // REQUIRED: The main title of the list item.
    title: string,
    // OPTIONAL: A secondary title.
    subtitle: string,
    // OPTIONAL: Additional labeling which appears directly below the title or subtitle label: String,
    // OPTIONAL: If provided, a date will always appear at the top of the list item
    date: Date,
    // OPTIONAL: An array of actions which are appended to the right side of the list item.
    actions: [
        {
            label: string | JSX.Element,
            action: Function
        }
    ]
}

A developer gave me an api specification which is a List that can accept an array of objects using the ListItem shape described below; this will be transformed into a set of rendered List.Item ponents.

API

The List ponent accepts the following props:

  • items (ListItem[]): Required. This array should contain one or more JSX elements, or one or more ListItem objects (see below for details).
  • searchable (string[]): Optional. Accepts an array of strings which match the names of ListItem properties. If present, a localized freeform search box is rendered above the list, and entry within that field will filter the internal data using the provided keys as a guide.

Schemas


ListItem

ListItem is the object schema for an individual item in the list.

{
    // REQUIRED: The main title of the list item.
    title: string,
    // OPTIONAL: A secondary title.
    subtitle: string,
    // OPTIONAL: Additional labeling which appears directly below the title or subtitle label: String,
    // OPTIONAL: If provided, a date will always appear at the top of the list item
    date: Date,
    // OPTIONAL: An array of actions which are appended to the right side of the list item.
    actions: [
        {
            label: string | JSX.Element,
            action: Function
        }
    ]
}


My implementation which is not working

journalList.jsx

import PropTypes from "prop-types";
import React from "react";
import {Components} from "reusable-web-ponents";

const {
    Icon,
    List
} = Components;

const JournalList = (props) => {
  const {description, title} = props;
  
  const formattedItems = [
    {
        title: title,
        description: description,
        actions: [
            {
                label: <Icon name="edit" />,
                action: () => {}
            },
            {
                label: <Icon name="delete" />,
                action: () => {}
            }
        ]
    }
];
    return(
        <List items={formattedItems} searchable={["title"]} />
    )
}

JournalList.propTypes = {
  "title": PropTypes.string.isRequired,
  "description": PropTypes.string.isRequired
};

JournalList.defaultProps = {
    
};

export default JournalList;


Now here is the parent ponent

journal.jsx

import api from "bees";
import JournalList from './JournalList';
import React from "react";
import store from "store";


class Journal extends React.Component {
    constructor (props) {
        super(props)
        this.state = {
            "displayList": true,
            "journalList": null,
            "searchJournalList": []
        }
    }

    ponentDidMount = () => {
        store.dispatch(api.getJournals()).then((result) => {
            this.setState(() => ({"journalList": result.body.data}));
        }).
            catch(() => {
                this.setState(() => ({"journalList": []}));
            });
    }

    onEdit = () => {
        // TODO: Update a Journal
    }

    onDelete = () => {
        // TODO: Delete a Journal 
    }
    render() {
        return (
            <div>
               
                    <JournalList>
                        {
                            journalList.map((items) => {
                                return{
                                    key={items.title}
                                        title={items.title} 
                                        description={items.description} 
                                }
                            })                            
                        }
                    </JournalList>
               
            </div>            
        ) 
    }   
}


export default Journal;

I need to be able to successfully iterate over the data I am getting from my store and create a list of journal entries. According to his documentation the output should look like this:

<div>
  <div class="list">
    <div class="list__search">
      <div class="form-group">
        <input placeholder="Search" id="ListSearch_0.1429790340540955" class="form-control">
      </div>
    </div>
    <div class="list__item">
      <div class="list-item">
        <div class="list-item__contents">
          <div class="list-item-contents">
            <div class="list-item-contents__title">Journal 1</div>
            <div class="list-item-contents__title">Journal 2</div>
          </div>
        </div>
        <div class="list-item__actions">
          <button class="list-item-action"><svg class="icon icon--medium"><use xlink: href="#edit-icon"></use></svg></button>
          <button class="list-item-action"><svg class="icon icon--medium"><use xlink: href="#delete-icon"></use></svg></button>
        </div>
      </div>
    </div>
  </div>
</div>

Share Improve this question asked Jun 14, 2018 at 16:49 Amen RaAmen Ra 2,85110 gold badges49 silver badges87 bronze badges 0
Add a ment  | 

1 Answer 1

Reset to default 2

The render method of your Journal ponent should be like:

render() {
    return (
        <div>
            {this.state.journalList.map((items) => {
                <JournalList key={items.title}
                             title={items.title} 
                             description={items.description}>
                </JournalList>
                       })                            
            }
        </div>            
    ) 
} 

And change the state declaration to:

this.state = {
        displayList: true,
        journalList: [],
        searchJournalList: []
    }

You've reversed the order of the things. The map() should wrap the ponent <JournalList>, instead of the <JournalList> wrap the journalList.map(). Because the map will iterate through the journalList and create each ponent.

EDIT:

Your JournalList ponent is "unuseful". It is creating multiple lists, but you only needs one. Change your <JournalList> to this:

import PropTypes from "prop-types";
import React from "react";
import {Components} from "reusable-web-ponents";
import store from "store"

const {
    Icon,
    List
} = Components;

const JournalList = (props) => {
    state = {
       journalList: []
    }
    ponentDidMount = () => {
        store.dispatch(api.getJournals()).then((result) => {
            var formattedItems = result.body.data.map( data => {
              title: data.title,
              description: data.description,
                 actions: [
                    {
                       label: <Icon name="edit" />,
                       action: () => {}
                    },
                    {
                       label: <Icon name="delete" />,
                       action: () => {}
                    }
                 ] 
              }) // End of the map
            this.setState(() => ({"journalList": formattedItems}));
        }).
            catch(() => {
                this.setState(() => ({"journalList": []}));
            });
    }
    render(){
       return(
          <List items={this.state.journalList} searchable={["title"]} />
       )
    }
}

export default JournalList;

Doing this, you JournalList ponent will be useful, and you won't need the <Journal> Component.

本文标签: javascriptHow do I create a react list component from an array of objectsStack Overflow