Попытка сопоставить массив объектов условно - PullRequest
0 голосов
/ 11 января 2019

Я пытаюсь условно визуализировать некоторый контент на экране. По сути, у меня есть массив из 3 объектов с некоторыми вложенными объектами. Этот главный объект хранится в моем редукторе в качестве исходного состояния (это некоторые фиктивные данные). У меня есть панель Sidenav, на которой есть несколько ссылок, и я хочу визуализировать контент в правой части боковой панели. Я использую пользовательский sidenav, поэтому он может показаться немного запутанным, но моя проблема в том, что мне нужно каким-то образом отобразить этот массив из 3 объектов, чтобы я мог отображать каждый объект на основе ссылки, по которой щелкает пользователь. Я опубликую часть объекта, на которую я смотрю (на самом деле я уже публиковал вопрос об этом раньше, если вы хотите увидеть весь объект). Я младший Dev, так что я уверен, что это не что-то слишком сложное.

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

и вот объект, с которым я работаю через редуктор

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 голосов
/ 11 января 2019

Сделайте ExampleMenu компонентом parentComponent для 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
    })
  }

Добавьте ваш JSX в ваш render()

{ (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} /> }

И используйте device как props в вашем Chosen или RightSideOfTheNav компоненте

Надеюсь, это то, что вам нужно.

0 голосов
/ 11 января 2019

Вам нужно будет сохранить выбранную категорию (device, laptop или mobile) в состоянии вашего компонента:

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

Чтобы получить нужные данные, используйте функцию поиска, чтобы узнать, какой объект содержит выбранный ключ:

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'/>
0 голосов
/ 11 января 2019

Вы можете использовать состояние, например 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> ) }

  }

Вы пытаетесь сделать что-то подобное выше?

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...