简体   繁体   English

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

[英]Trying to map an array of objects conditionally

I'm trying to conditionally render some content on a screen. 我试图有条件地在屏幕上呈现一些内容。 Basically, I have an array of 3 objects with some sub objects. 基本上,我有3个对象的数组和一些子对象。 This main object is stored in my reducer as the initial state (it is some dummy data). 这个主要对象作为初始状态存储在我的reducer中(它是一些伪数据)。 I have a Sidenav bar which has some links and I want to render some content to the right side of the side nav. 我有一个Sidenav栏,其中包含一些链接,我想在侧面导航的右侧呈现一些内容。 I am using a custom sidenav so it may look a bit confusing, but my problem is I need to somehow map this array of 3 objects so I can render each object based on which link the user clicks. 我正在使用自定义sidenav,因此看起来可能有些混乱,但是我的问题是我需要以某种方式映射3个对象的数组,以便可以根据用户单击的链接来渲染每个对象。 I will post the portion of the object that I am looking at (I actually posted a question about this earlier if you want to see the whole object). 我将发布正在查看的对象的一部分(如果您想查看整个对象,我实际上已在前面发布了有关此问题的问题)。 I'm a jr. 我是小 dev so I'm sure this isn't something too complex. 开发人员,所以我确定这不是太复杂。

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);

and here is the object I am working with through the 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"
                  }
                ]
              }
            }
          ]
        }
      }
};

The product array with the 3 objects is what I was referring to. 我指的是具有3个对象的产品数组。 I also have some random functions just to see if I was getting the data or not with console.logs but ideally I want to use that onClickAny function to render either of the three objects on the right side (maybe in a list) based on whether someone clicked the devices, mobile, or laptop buttons. 我还具有一些随机函数,只是为了查看是否通过console.logs获取数据,但理想情况下,我想基于是否是否使用onClickAny函数在右侧(可能在列表中)呈现三个对象中的任何一个有人点击了设备,手机或笔记本电脑上的按钮。 Please, any help would be greatly appreciated! 请任何帮助将不胜感激!

You can use a state such as deviceType and change it to laptop when laptop is clicked. 您可以使用诸如deviceType之类的状态,并在单击laptop时将其更改为laptop电脑。 And render it like 并像

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

Does that make sense? 那有意义吗?

Let's start with an easy example: 让我们从一个简单的例子开始:

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> ) }

  }

Are you trying to do something like the above? 您是否正在尝试执行上述操作?

Make ExampleMenu as parentComponent to RightSideOfTheNav component (this is where you want to display your device info) or you can use your Chosen component ExampleMenuRightSideOfTheNav组件的parentComponent(在此处您要显示设备信息),或者可以使用Chosen组件

Add state to your ExampleMenu component 将状态添加到您的ExampleMenu组件

state = {
    requiredDevice: {}
} 

Update your button in your JSX 更新您的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>

Here we are passing arguments to this.onClickAny('devices') statically. 在这里,我们将参数静态传递给this.onClickAny('devices')

Update your onClickAny method 更新您的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
    })
  }

Add in your JSX in your render() render()添加JSX

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

or maybe in your case it is Chosen component so 或者在您的情况下,它是Chosen组件,所以

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

And Use device as props in your Chosen or RightSideOfTheNav component 并在您ChosenRightSideOfTheNav组件RightSideOfTheNav device用作props

Hope this is what you need. 希望这是您所需要的。

You will have to store the selected category( device , laptop or mobile ) in your component's state : 您将必须以组件的状态存储所选类别( devicelaptopmobile ):

this.state = {
    selection: 'device'
}

Now give your button's a function pre-configured with the category they represent : 现在,为按钮的功能预先配置它们所代表的类别:

<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>

And now, the new function to set your state depending on which one got clicked : 现在,新功能可以根据您单击的状态来设置状态:

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

To get the data you want, use the find function to know what object contains the selected key : 要获取所需的数据,请使用find函数来了解哪个对象包含所选键:

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

Fully functional example : 功能齐全的示例:

 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'/> 

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM