尝试有条件地映射对象数组

时间:2019-01-11 07:28:16

标签: javascript arrays reactjs object redux

我正在尝试有条件地在屏幕上呈现某些内容。基本上,我有3个对象的数组和一些子对象。这个主要对象作为初始状态存储在我的reducer中(它是一些伪数据)。我有一个Sidenav栏,其中包含一些链接,我想在侧面导航的右侧呈现一些内容。我正在使用自定义sidenav,因此看起来可能有些混乱,但是我的问题是我需要以某种方式映射3个对象的数组,以便可以根据用户单击的链接来渲染每个对象。我将发布正在查看的对象的一部分(如果您想查看整个对象,我实际上已在前面发布了有关此问题的问题)。我是小开发人员,所以我确定这不是太复杂。

import React, { Component } from 'react';
import { connect } from 'react-redux';
import ReduxBurgerMenu from '../components/Menu';
import Chosen from '../components/Chosen';

class ExampleMenu extends Component {

  onClickDevices = (props) => {
    let devices = this.props.product;
    console.log(devices)
  }

  onClickLaptops = (props) => {
    let laptops = this.props.product[1];
    console.log(laptops)
  }

  onClickMobile = (props) => {
    let mobile = this.props.product[2];
    console.log(mobile)
  }

  onClickAny = (props) => {
    let devices = this.props.product;
    devices.map(obj => {
      return Object.keys(obj).map(key => {
        return (
          <tr>
            <td>{key}</td>
            <td>{obj[key]}</td>
          </tr>
        )
      })
    })
  }

    render () {
        let first = Object.keys(this.props.menu.products)[0];
        let second = Object.keys(this.props.menu.products)[1];

        return (
            <ReduxBurgerMenu isOpen={ this.props.isOpen }>
                <a href="javascript:void(0)">{this.props.menu.title}</a>
                <a href="javascript:void(0)">{this.props.menu.description}</a>
                <a href="javascript:void(0)">{first}</a>
                <a href="javascript:void(0)">{second}</a>
                <button onClick={this.onClickDevices} id="Devices" className="menu-item" href="/">Devices</button>
                <button onClick={this.onClickAny} id="Laptop" className="menu-item" href="/laptops">{}</button>
                <button onClick={this.onClickMobile} id="Mobile" className="menu-item" href="/mobile">Mobile</button>
                <Chosen />
            </ReduxBurgerMenu>
        );
    }
}

// {JSON.stringify(this.props.products)}

const mapStateToProps = state => {
  return {
    menu: state.reducer.menu,
    product: state.reducer.menu.products.product
  }
}

export default connect(mapStateToProps)(ExampleMenu);

这是我通过reducer使用的对象

const initialState = {
  menu: {
        title: "Menu title",
        description: "Menu description",
        products: {
          title: "Products title",
          description: "Product description",
          product: [
            {
              device: {
                title: "Device title",
                description: "Device description",
                types: [
                  {
                    name: "Modem",
                    title: "Modem title",
                    description: "Modem description"
                  },
                  {
                    name: "charger",
                    title: "charger title",
                    description: "charger description"
                  }
                ]
              }
            },
            {
              laptop: {
                title: "Laptop title",
                description: "Laptop description",
                types: [
                  {
                    name: "Apple",
                    title: "Apple title",
                    description: "Apple description"
                  },
                  {
                    name: "Lenevo",
                    title: "Lenevo title",
                    description: "Lenevo description"
                  }
                ]
              }
            },
            {
              mobile: {
                title: "Mobile title",
                description: "Mobile description",
                types: [
                  {
                    name: "Samsung",
                    title: "Samsung title",
                    description: "Samsung description"
                  },
                  {
                    name: "Nokia",
                    title: "Nokia title",
                    description: "Nokia description"
                  }
                ]
              }
            }
          ]
        }
      }
};

我所指的是具有3个对象的产品数组。我还具有一些随机函数,只是为了查看是否通过console.logs获取数据,但理想情况下,我想基于是否是否使用onClickAny函数在右侧(可能在列表中)呈现三个对象中的任何一个有人点击了设备,手机或笔记本电脑上的按钮。请任何帮助将不胜感激!

3 个答案:

答案 0 :(得分:0)

您可以使用诸如deviceType之类的状态,并在单击笔记本电脑时将其更改为laptop。 并将其渲染为

{ this.state.deviceType === 'mobile' && <div>Render this</div>}
{ this.state.deviceType === 'web' && <div>Render this thing</div>}

这有意义吗?

让我们从一个简单的示例开始:

onClickDevices = (props) => {
    let devices = this.props.product[0];
    let types = devices.types;
    return types.map((type) => {
       return (
         <tr>
            <td>{type.name}</td>
            <td>{type.title}</td>
            <td>{type.description</td>
         </tr> ) }

  }

您是否正在尝试执行上述操作?

答案 1 :(得分:0)

ExampleMenu作为RightSideOfTheNav组件的父组件(在这里您要显示设备信息),或者可以使用Chosen组件

将状态添加到您的ExampleMenu组件

state = {
    requiredDevice: {}
} 

更新您的JSX中的按钮

<button onClick={() => this.onClickAny('device')} id="Devices" className="menu-item" href="/">Devices</button>
<button onClick={() => this.onClickAny('laptop')} id="Laptop" className="menu-item" href="/laptops">Laptop</button>
<button onClick={() => this.onClickAny('mobile')} id="Mobile" className="menu-item" href="/mobile">Mobile</button>

在这里,我们将参数静态传递给this.onClickAny('devices')

更新您的onClickAny方法

onClickAny = (productType) => {
    let devices = this.props.product;
    var requiredDevice = devices.find(itemDevice => itemDevice.hasOwnProperty(productType))[productType]
    // if 'device' is passed as 'productType' 
    // var requiredDevice = devices.find(itemDevice => itemDevice.hasOwnProperty('device'))['device']
    // it returns
     // {
     //     title: "Device title",
     //     description: "Device description",
     //     types: [
     //              {
     //                name: "Modem",
     //                title: "Modem title",
     //                description: "Modem description"
     //              },
     //              {
     //                name: "charger",
     //                title: "charger title",
     //                description: "charger description"
     //              }
     //            ]
     // }
    this.setState({
        requiredDevice
    })
  }

render()中添加JSX

{ (Object.keys(this.state.requiredDevice).length > 0) && <RightSideOfTheNav device={this.state.requiredDevice} /> }

或者在您的情况下,它是Chosen组件

{ (Object.keys(this.state.requiredDevice).length > 0) && <Chosen device={this.state.requiredDevice} /> }

并在您的deviceprops组件中将Chosen用作RightSideOfTheNav

希望这就是您所需要的。

答案 2 :(得分:0)

您将必须以组件状态存储选定的类别(devicelaptopmobile

this.state = {
    selection: 'device'
}

现在为按钮提供一个功能,该功能已预先配置为它们代表的类别:

<button onClick={this.changeSlection('device')} id="Devices" className="menu-item" >Devices</button>
<button onClick={this.changeSlection('laptop')} id="Laptop" className="menu-item" >Laptop</button>
 <button onClick={this.changeSlection('mobile')} id="Mobile" className="menu-item" >Mobile</button>

现在,新功能可以根据您点击的状态来设置您的状态:

changeSlection = selection => ev => {
    this.setState({ selection })
}

要获取所需的数据,请使用find函数知道哪个对象包含所选键:

const selectedProduct = product.find(p => p[selection])[selection]

完整的功能示例:

class App extends React.Component {
    constructor(props) {
        super(props)

        this.state = {
            selection: 'device',
            product: [
                {
                    device: {
                        title: "Device title",
                        description: "Device description",
                        types: [
                            {
                                name: "Modem",
                                title: "Modem title",
                                description: "Modem description"
                            },
                            {
                                name: "charger",
                                title: "charger title",
                                description: "charger description"
                            }
                        ]
                    }
                },
                {
                    laptop: {
                        title: "Laptop title",
                        description: "Laptop description",
                        types: [
                            {
                                name: "Apple",
                                title: "Apple title",
                                description: "Apple description"
                            },
                            {
                                name: "Lenevo",
                                title: "Lenevo title",
                                description: "Lenevo description"
                            }
                        ]
                    }
                },
                {
                    mobile: {
                        title: "Mobile title",
                        description: "Mobile description",
                        types: [
                            {
                                name: "Samsung",
                                title: "Samsung title",
                                description: "Samsung description"
                            },
                            {
                                name: "Nokia",
                                title: "Nokia title",
                                description: "Nokia description"
                            }
                        ]
                    }
                }
            ]
        }
    }

    changeSlection = selection => ev => {
        this.setState({ selection })
    }

    render() {
        const { product, selection } = this.state
        const selectedProduct = product.find(p => p[selection])[selection]

        return (
            <div>
                <button onClick={this.changeSlection('device')} id="Devices" className="menu-item" >Devices</button>
                <button onClick={this.changeSlection('laptop')} id="Laptop" className="menu-item" >Laptop</button>
                <button onClick={this.changeSlection('mobile')} id="Mobile" className="menu-item" >Mobile</button>
                <h5>{selectedProduct.title}</h5>
                <p>{selectedProduct.description}</p>
                {/* <MyComponent data={selectedProduct}/> */}
            </div>
        )
    }
}


ReactDOM.render(<App/>, document.getElementById('root'))
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.6.0/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.6.0/umd/react-dom.production.min.js"></script>
<div id='root'/>