如何从javascript数组对象/ JSON获取数据并在React JS中使用它们

时间:2019-01-19 16:29:49

标签: javascript json reactjs

我正在开发一个React Js网站。我在其中有一个带有4个选择字段的表格,其中包括制造,型号,最低价格和最高价格。我有一个JavaScript文件,其中包含汽车的制造商和型号。 文件包含多个汽车品牌。文件数据可在下面获得,这些数据代表Car Make及其阵列中的可用模型。

export const veh_data = [{"alfa-romeo": ["145", "90", "Alfa 6", "Alfasud"]},
{"aston-martin": ["15", "2-Litre", "AM Vantage", "Atom", "Cygnet", "DB2"]},
{"audi": ["100", "200", "A1", "A2", "A3", "A4", "A5", "A6", "A7" ]}
];

我想从该文件中获取该数据(名称(例如audi)及其型号),并将该数据显示为表单中“选择”字段的选项。

这是我的React JS组件代码:

import React, { Component } from 'react';
import { Form, FormGroup, Input } from 'reactstrap';
import { veh_data } from '../shared/vehicle_make_and_models'

class ImgAndForm extends Component {
constructor(props) {
    super(props);

    this.handleSearch = this.handleSearch.bind(this);

    this.state = {
        veh_data: veh_data,
    };

}

handleSearch(event) {
    alert("Search button clicked");
    event.preventDefault();

}

render() {

    const veh_make = this.state.veh_data.map((veh) => {
        return (
          <div>
              <option></option>
          </div>
        );
    });

    return (
        <div>
            <header className="headerbg d-flex">
                <div className="container my-auto">
                    <div className="row">
                        <div className="offset-1 col-10 offset-lg-0 col-lg-4">
                            <div id="search-form-div" className="container">
                                <div className="row">
                                    <div className="col-12 my-4">
                                        <h3>Search</h3>
                                        <Form onSubmit={this.handleSearch}>
                                            <FormGroup>
                                                <Input type="select" name="select1" id="select1">
                                                    <option value="">Make</option>
                                                    {veh_make}
                                                </Input>
                                            </FormGroup>
                                            <FormGroup>
                                                <Input type="select" name="select2" id="select2">
                                                    <option value="">Model</option>
                                                    {veh_make}
                                                </Input>
                                            </FormGroup>
                                            <FormGroup>
                                                <Input type="select" name="select3" id="select3">
                                                    <option value="">Min Price</option>
                                                    <option value="500">500</option>
                                                </Input>
                                            </FormGroup>
                                            <FormGroup>
                                                <Input type="select" name="select4" id="select4">
                                                    <option value="">Max Price</option>
                                                    <option value="2000">2000</option>
                                                </Input>
                                            </FormGroup>
                                            <FormGroup>
                                                <Input type="submit" name="search" id="search" className="btn btn-primary" value="Search" />
                                            </FormGroup>
                                        </Form>
                                    </div>
                                </div>
                            </div>
                        </div>
                    </div>
                </div>
            </header>

        </div>
    );
}
}

export default ImgAndForm;

1 个答案:

答案 0 :(得分:0)

首先,您需要将车辆值解析为JSX options元素的单独数组。我更喜欢用reduce函数来做到这一点...

const vehicles = this.state.veh_data.reduce((acc, veh) => {
      let make = Object.keys(veh)[0],
          vehModels = veh[make];

      return {
            makes: [
                  ...acc.makes,
                  <option value={make}>{make}</option>
            ],
            models:[
                  ...acc.models,
                  ...vehModels.map(model => {
                       return <option value={model}>{model}</option>
                  })
            ]  
       };
},{makes:[], models:[]});

由于veh_data数组中的每个元素都是一个对象,因此您需要使用Object.keys()访问其第一个(也是唯一的)属性以获取该对象的所有键,然后只需抓住第一个(也是唯一的)键即可。

可以通过获取要迭代的每个veh对象中该键的值来访问模型

...

<FormGroup>
      <Input type="select" name="select1" id="select1">
      <option selected disabled>Make</option>
      {vehicles.makes}
      </Input>
</FormGroup>

...

<FormGroup>
  <Input type="select" name="select2" id="select2">
        <option selected disabled>Model</option>
        {vehicles.models}
  </Input>
</FormGroup>

...

考虑到上下文,我也不需要将veh_data存储到组件状态,除非资源会动态更新UI,否则这是资源的浪费。 / p>

https://jsfiddle.net/mfpv1L6s/

(注意:我了解这不会为您提供您“应该”寻求的完整解决方案,因为它将显示每辆车的模型选项,而不是仅显示与当前选择的“制造”相关的模型,但是这对您来说应该是一个很好的起点。)

额外信用:我还将解析选项表示形式的值,使其更具吸引力……

keyToOption(key){
        return key.split('-')
                .map(word=> word.slice(0,1).toUpperCase + word.slice(1))
                .join(' ');
 }

然后像这样将其添加到reduce函数中...

makes: [
    ...acc.makes,
    <option value={make}>{this.keyToOption(make)}</option>
],

我已将上述内容包含在JSFiddle中

(完整的工作示例。...)

import React, { Component } from "react";
import { Form, FormGroup, Input } from "reactstrap";
// import { veh_data } from '../shared/vehicle_make_and_models'
const veh_data = [
  { "alfa-romeo": ["145", "90", "Alfa 6", "Alfasud"] },
  { "aston-martin": ["15", "2-Litre", "AM Vantage", "Atom", "Cygnet", "DB2"] },
  { audi: ["100", "200", "A1", "A2", "A3", "A4", "A5", "A6", "A7"] }
];

const vehicles = parseVehicleList(veh_data)

class ImgAndForm extends Component { 
  state = { modelSelected: null };

  handleSearch(event) {
    alert("Search button clicked");
    event.preventDefault();
  }

  handleModelChange(event) {
    console.log(event.target.value);
    this.setState({ modelSelected: event.target.value });
  }

  render() {
    const selectedModels =
      this.state.modelSelected && this.state.modelSelected.length ? (
        vehicles.models[this.state.modelSelected]
      ) : (
        <option value="">(Please Select Make)</option>
      );

    return (
      <div>
        <header className="headerbg d-flex">
          <div className="container my-auto">
            <div className="row">
              <div className="offset-1 col-10 offset-lg-0 col-lg-4">
                <div id="search-form-div" className="container">
                  <div className="row">
                    <div className="col-12 my-4">
                      <h3>Search</h3>
                      <Form onSubmit={this.handleSearch}>
                        <FormGroup>
                          <Input
                            onChange={e => this.handleModelChange(e)}
                            type="select"
                            name="select1"
                            id="select1"
                          >
                            <option value="">Make</option>
                            {vehicles.makes}
                          </Input>
                        </FormGroup>
                        <FormGroup>
                          <Input type="select" name="select2" id="select2">
                            {selectedModels}
                          </Input>
                        </FormGroup>
                        <FormGroup>
                          <Input type="select" name="select3" id="select3">
                            <option value="">Min Price</option>
                            <option value="500">500</option>
                          </Input>
                        </FormGroup>
                        <FormGroup>
                          <Input type="select" name="select4" id="select4">
                            <option value="">Max Price</option>
                            <option value="2000">2000</option>
                          </Input>
                        </FormGroup>
                        <FormGroup>
                          <Input
                            type="submit"
                            name="search"
                            id="search"
                            className="btn btn-primary"
                            value="Search"
                          />
                        </FormGroup>
                      </Form>
                    </div>
                  </div>
                </div>
              </div>
            </div>
          </div>
        </header>
      </div>
    );
  }
}

export default ImgAndForm;

function parseVehicleList(data) {
  return data.reduce(
    (acc, veh, i) => {
      let make = Object.keys(veh)[0],
        vehModels = veh[make];

      return {
        makes: [
          ...acc.makes,
          <option key={make + i} value={make}>
            {keyToOption(make)}
          </option>
        ],
        models: {
          ...acc.models,
          [make]: vehModels.map((model, i) => {
            return (
              <option key={make + model + i} value={model}>
                {keyToOption(model)}
              </option>
            );
          })
        }
      };
    },
    { makes: [], models: {} }
  );
}

function keyToOption(key) {
  return key
    .split("-")
    .map(word => word.slice(0, 1).toUpperCase() + word.slice(1))
    .join(" ");
}