如何在 ReactJS 中循环来自外部文件的 JSON 数据?

Posted

技术标签:

【中文标题】如何在 ReactJS 中循环来自外部文件的 JSON 数据?【英文标题】:How to loop over JSON data from external file in ReactJS? 【发布时间】:2018-08-04 07:53:00 【问题描述】:

我制作了 2 个按钮和一个输入字段。按钮 (+/-) 用于增加和减少计数器。最初输入字段的内容是日期,即data.available_slots[0].date

当我通过单击 + 按钮递增时,日期会从 Wed, Dec 06 动态更改为 Thur, Dec07Fri, Dec08 等等,直到最后一个日期,即 Wed, Dec13

JSONdata 的长度为 7,即 data.available_slots[0].datedata.available_slots[6].date,因此当计数器达到 6 时,它不应进一步增加,如果计数器减少,则不应低于 0。

但是现在当计数器(索引)超出范围时,它会显示错误(见截图)

查看点击按钮在输入字段https://imgur.com/a/aek4e中显示各种日期的各种屏幕截图

datepicker.js:

import React,  Component  from 'react';
import data from './data';
import './datepicker.css';

class DatePicker extends Component 

  constructor(props)
    super(props);
     this.state = 
        counter:0
     ;
   

  increment()
    this.setState(
      counter: this.state.counter + 1
    );
  

  decrement()
    if(this.state.counter > 0)
      this.setState(prevState => (counter: prevState.counter-1))
   
  


  render() 
    return (
      <div>
        <div id="center">
            <label for="name">Pick a Date </label>
            <p></p>
            <button type="button" className="btn btn-success" id="plus" onClick=this.increment.bind(this)>+</button>
            <input type="text" id="date" value=data.available_slots[this.state.counter].date/>
            <button type="button" className="btn btn-danger" id="minus" onClick=this.decrement.bind(this)>-</button> 
        </div>
      </div>
    );
  


export default DatePicker;

data.js:

const data = 
        "template_type": "slot_picker",
        "selection_color": "#000000",
        "secondary_color": "#808080",
        "title": "Available Slots for Dr. Sumit",
        "available_slots": [
          
            "date": "Wed, Dec 06",
            "date_slots": [

            ]
          ,
          
            "date": "Thu, Dec 07",
            "date_slots": [

            ]
          ,
          
            "date": "Fri, Dec 08",
            "date_slots": [

            ]
          ,
          
            "date": "Sat, Dec 09",
            "date_slots": [

            ]
          ,
          
            "date": "Today",
            "date_slots": [
              
                "hour": "8",
                "hour_slots": [
                  
                    "08:10 AM": "slotId001"
                  ,
                  
                    "08:50 AM": "slotId005"
                  
                ]
              ,
              
                "hour": "3",
                "hour_slots": [
                  
                    "03:00 PM": "slotId005"
                  ,
                  
                    "03:30 PM": "slotId007"
                  
                ]
              
            ]
          ,
          
            "date": "Tomorrow",
            "date_slots": [

            ]
          ,
          
            "date": "Wed, Dec 13",
            "date_slots": [
              
                "hour": "4",
                "hour_slots": [
                  
                    "04:30 PM": "slotId105"
                  ,
                  
                    "04:50 PM": "slotId106"
                  
                ]
              ,
              
                "hour": "5",
                "hour_slots": [
                  
                    "05:30 PM": "slotId202"
                  ,
                  
                    "05:45 PM": "slotId208"
                  
                ]
              
            ]
          
        ]
      ;

 export default data;

enter image description here

【问题讨论】:

可以在返回前测试输入值抑制越界错误。 检查是否(计数器> data.available_slots.length)然后再次将计数器设置为默认值 @javed JSONdata 的长度是 7 即 data.available_slots[0].datedata.available_slots[6] 所以当计数器达到 6 时它不应该进一步增加,如果计数器减少那么它不应该低于 0 如何处理这个。 @ladjzero JSONdata 的长度是 7 即 data.available_slots[0].datedata.available_slots[6].date 所以当计数器达到 6 时它不应该进一步增加,如果计数器减少那么它不应该低于 0 如何处理这个 我认为这不是一个反应问题。你可以缩小你的问题。让 count = (count + length) % 长度返回。 【参考方案1】:

在增加它的值之前检查计数器值。像这样:

increment()
    if(this.state.counter < 6)
        this.setState(
            counter: this.state.counter + 1
        );

或者

increment()
    this.setState(prevState => (
        counter: prevState.counter < 6? (prevState.counter+1): prevState.counter
    ));

【讨论】:

为什么它不能 将为 false) value 将不会增加,但如果你使用 我建议使用data.available_slots.length - 1 而不是硬编码的6 值,这样您就不必在数据更改时更新该硬编码值。 @TimNovis 伙计,你为什么要评论我的答案,评论你的答案操作会收到通知:P【参考方案2】:
increment()
    this.setState(
      counter: this.state.counter == data.available_slots.length ? 0 :  this.state.counter + 1
    );
  

【讨论】:

【参考方案3】:

据我所知,您正试图阻止此错误出现。如果您的数据文件中没有更多日期,您可以通过禁用“加号”按钮来解决此问题。

例如,在您的渲染函数中,您可以执行以下操作:

render() 
    const maxDateIndex = data.available_slots.length - 1;
    return (
      <div>
        <div id="center">
          <label for="name">Pick a Date </label>
          <button
            disabled=this.state.counter >= maxDateIndex
            type="button"
            className="btn btn-success"
            id="plus"
            onClick=this.increment.bind(this)
          >
            +
          </button>
          <input
            type="text"
            id="date"
            value=data.available_slots[this.state.counter].date
          />
          <button
            type="button"
            className="btn btn-danger"
            id="minus"
            onClick=this.decrement.bind(this)
          >
            -
          </button>
        </div>
      </div>
    );
  

【讨论】:

【参考方案4】:

只是想提一下,对于带有重置的增量,这非常有效:

this.setState(
   counter: (this.state.counter + 1) % data.available_slots.length
)

【讨论】:

以上是关于如何在 ReactJS 中循环来自外部文件的 JSON 数据?的主要内容,如果未能解决你的问题,请参考以下文章

如何从定义在和/或动态 id 元素名称的 JS 类外部渲染 ReactJS 组件?

从 ReactJS 外部渲染组件

如何使用外部 css 在 Reactjs 中设置背景图像?

Reactjs Access类方法在类外部,但在同一文件中

React JS - 从外部属性文件中读取配置?

如何在两个不同的组件中使用路由 - ReactJS