设置带有API json对象的动态菜单?

时间:2019-05-10 17:00:31

标签: javascript json reactjs api object

我不确定该怎么做...所以我要调用API数据(只是一堆嵌套的json对象)来创建菜单。到目前为止,我一直在使用它,以便它呈现对象的第一层(第一张img),当您单击每个元素时,下一层将显示在它下面(第二张img)。这是递归的,因此我认为当我单击“级别2”中的元素时,它可以在下一个级别工作,但是不是这种情况。

谁能看到我可以在代码中进行哪些更改以使其正常工作?

class Menu extends React.Component {
  state = {
    categories: [],
    list: ""
  };


  //handle displaying list of values when clicking on button
  //search for list of values within object
  handleSearch = (obj, next, event) => {
    // console.log(event.target.name);
    Object.keys(obj).forEach(key => {
      if (typeof obj[key] === "object") {
        if (next === key) {
          //create DOM  CHILDREN
          createData(Object.keys(obj[key]), key, this.test, event);
        }
        this.handleSearch(obj[key], next);
      }
    });
  };

  componentDidMount() {
    axios.get("https://www.ifixit.com/api/2.0/categories").then(response => {
      this.setState({ categories: response.data });
    });
  }

  render() {
    return (
      <React.Fragment>
        {/* display list of things */}
        <div className="columns is-multiline">
          {Object.keys(this.state.categories).map(key => (
            <div className="column is-4">
              <div
                onClick={event =>
                  this.handleSearch(this.state.categories, key, event)
                }
              >
                {key}
              </div>
              <div name={key + "1"} />
            </div>
          ))}
        </div>
      </React.Fragment>
    );
  }
}

这是createData的代码,该代码创建下一级别的数据,并且应该将其制作为可以单击这些元素以显示下一级别的数据

var index = 1;
export function createData(data, key, search, e) {
  e.stopPropagation();
  let parent = document.getElementsByName(key + "1");

  //create elements and append them
  for (let i = 0; i < data.length; i++) {
    let wrapper = document.createElement("ul");
    wrapper.innerHTML = data[i];
    wrapper.name = data[i] + index + 1;
    wrapper.addEventListener("click", search(data[i]));
    parent[0].append(wrapper);
  }
}

first level of objects second level

这是控制台中“类别”的屏幕快照(对象内的对象在对象内) categories

2 个答案:

答案 0 :(得分:1)

如果可能的话,您应该尝试在使用React的同时使用香草JS创建/附加元素来避免操作DOM,它的主要优势之一是虚拟DOM,它可以为您管理渲染并避免冲突。

不确定要渲染的对象的深度,但是由于数据的复杂性,这是使用另一个组件对事物进行模块化并避免您现在要处理的混乱情况的好例子。

假设所有子对象的结构相同,则可以创建一个组件,该组件根据对象键递归地呈现自身。 This answer应该有帮助。

答案 1 :(得分:1)

为简单起见,我们将递归渲染此嵌套对象,该嵌套对象的结构为您的categories对象:

const categories = {
  level1: {
    "level1-1": {
      "level1-1-1": {
        "level1-1-1-1": {}
      }
    },
    "level1-2": {
      "level1-2-1": {}
    }
  },
  level2: {}
};

递归结束条件将是没有keys的对象。

对于每一层,渲染keys并进行递归步骤。

const makeMenuLayer = layer => {
  const layerKeys = Object.entries(layer).map(([key, value]) => (
    <>
      {key}
      {makeMenuLayer(value)}
    </>
  ));
  return <div>{layerKeys}</div>;
};

结果:

level1
level1-1
level1-1-1
level1-1-1-1
level1-2
level1-2-1
level2

签出沙箱示例。

Edit o49onn9n45