Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to generate and render unordered list from an Object in React/Redux?

I need to render unordered list made from the object values (not array!):

//STATE---------------------------------------------------------------------
var BooksListStore = function(){
var BooksObject = {

    a: '1st book name',
    b: '2nd book name',
    c: '3rd book name'

};

return BooksObject;
};
//STATE---------------------------------------------------------------------

I'm trying to render this list in my BooksList component using for-in method:

//COMPONENT BOOKSLIST--------------------------------------------------------
const BooksList = ({ DataInputParam1, BtnClickHandler1 }) => {

function Normalizer(){

    var key
    var txt

    for (key in DataInputParam1){
        txt = DataInputParam1[key];
        return <li>{txt}</li>
        }

}

return(
    <div>
        <button onClick={() => BtnClickHandler1()}>Add Books</button>

        <ul>{Normalizer()}</ul>

    </div>
);

};
//COMPONENT BOOKSLIST--------------------------------------------------------

As a result i'm getting this - only first value gets rendered and no errors in the console:

enter image description here

Also i'm trying to do it this way:

const BooksList = ({ DataInputParam1, BtnClickHandler1 }) => {

Object.keys(DataInputParam1).map((listItem) => {
return (
<h2>{DataInputParam1[listItem]}</h2> 
     )
})
}

And getting error in the console: Error: BooksList(...): A valid React element (or null) must be returned. You may have returned undefined, an array or some other invalid object.

My entire code:

import React, {Component} from 'react';
import ReactDOM from 'react-dom';
import {createStore, compose, combineReducers} from 'redux';
import {Provider, connect} from 'react-redux';



//STATE---------------------------------------------------------------------
var BooksListStore = function(){
var BooksObject = {

    a: '1st book name',
    b: '2nd book name',
    c: '3rd book name'

//      a: {
//          title: '1st book name',
//          description: 'first book'
//      },
//
//      b: {
//          title: '2nd book name',
//          description: 'second book'
//      },
//
//      c: {
//          title: '3rd book name',
//          description: 'third book'
//      }

    };

    return BooksObject;
};
//STATE---------------------------------------------------------------------



//REDUCER-------------------------------------------------------------------
function BooksReducer(state=BooksListStore(), action){

switch(action.type){

case 'INCREASEBOOKQTY': 
    return Object.assign( {}, state, {d: '4th book name'}, {e: '5th book 
    name'}, {f: '6th book name'} );
default: 
    return state;
 }

}

const allReducers = combineReducers({BooksReducer});
//REDUCER--------------------------------------------------------------------



//COMPONENT BOOKSLIST--------------------------------------------------------
const BooksList = ({ DataInputParam1, BtnClickHandler1 }) => {

function Normalizer(){

var key
var txt

for (key in DataInputParam1){
    txt = DataInputParam1[key];
    return <li>{txt}</li>
    }

}

return(
    <div>
        <button onClick={() => BtnClickHandler1()}>Add Books</button>
        <ul>{Normalizer()}</ul>         
    </div>
);

};
//COMPONENT BOOKSLIST--------------------------------------------------------



//ROOT COMPONENT-------------------------------------------------------------
class RootComponent extends Component{


render() {
    return (
        <div>
            <BooksList DataInputParam1={this.props.books} BtnClickHandler1=
{this.props.addbooks}/>         
        </div>
    );
}
}

//ROOT COMPONENT---------------------------------------------------------------



//CONNECTING BOOKLIST COMPONENT TO THE STORE-----------------------------------
const mapStateToProps = (state) => {
return{
    books: state.BooksReducer
};
};

const mapDispatchToProps = (dispatch) => {
return {
    addbooks: () => dispatch({type: 'INCREASEBOOKQTY'}),
};
};

const App = connect(mapStateToProps, mapDispatchToProps)(RootComponent);
//CONNECTING BOOKLIST COMPONENT TO THE STORE-----------------------------------



//STORE------------------------------------------------------------------------
const composeEnchancers = window.__REDUX_DEVTOOLS_EXTENSION_COMPOSE__ || 
compose;
const store = createStore(allReducers, composeEnchancers());
//STORE------------------------------------------------------------------------



//RENDERING--------------------------------------------------------------------
ReactDOM.render(

<Provider store={store}>
    <App />
</Provider>, 

document.getElementById('app'));
//RENDERING--------------------------------------------------------------------

And what am i supposed to do if i also want to render values of object properties 'title' and 'description' which are disabled at the moment (commented lines)?

like image 763
KrasnokutskiyEA Avatar asked Mar 09 '23 08:03

KrasnokutskiyEA


2 Answers

function Normalizer(){
    return Object.keys(DataInputParam1).map(key => <li>{DataInputParam1[key]}</li>
}

And inside your render function

render(){
   return (
      <ul>
       { Normalizer() }
     </ul>
   );
}
like image 198
Avraam Mavridis Avatar answered Mar 11 '23 05:03

Avraam Mavridis


That's because you only return the first value. Try this:

function Normalizer(){

    var key
    var txt
    var list = []

    for (key in DataInputParam1){
        txt = DataInputParam1[key];
        list.push(<li key={key}>{txt}</li>);
    }

    return list;
}
like image 27
Win Avatar answered Mar 11 '23 05:03

Win