在React

时间:2018-05-25 15:19:44

标签: javascript reactjs express dictionary typeerror

我在一个物体内有多个阵列,用于不同类型的微量营养素(维生素,矿物质,抗氧化剂,氨基酸和Omega)。我想让每一个都作为<option>传递到他们自己的下拉菜单中,显示他们自己的类型(例如维生素:维生素B2,B6,B5等)

我的控制台显示数据已成功获取:

{vitamins: Array(6), minerals: Array(2), aminoacids: Array(1), antioxidants: Array(2), omegas: Array(1)}

但是当我到达Vitamins.js时,我试图呈现该选项,它说&#34; TypeError:vitamin.map不是一个功能&#34;。

这是我的Express服务器的res.json:

 router.get('/', function(req, res, next) {
 res.json({vitamins: [
  {
    name: "Vitamin B2"
  },
  {
    name: "Vitamin B6"
  }, 
  {
    name: "Vitamin B5"
  }
],
 minerals: [
  {
    name: "Calcium"
  },
 {
  name: "Zinc"
  }
 ] 
});
});

这是在Home.js中为res.json声明状态的地方。 (我知道&#34;用户&#34;现在没有任何语义意义,我会改变它。只是想弄清楚它为什么不首先工作。)

constructor(props) {
  super(props);
  this.state = {users: []};
 }

 componentDidMount() {
   fetch('/users')
      .then(res => res.json())
      .then(users => this.setState({ users }));
 }

 render() {
   return (
      <MenuItems users={this.state.users} />
  )
}

这是Menuitems.js,比Home.js向下一级,我在那里调用handleChange函数,所以当用户点击一个新的micro(维生素B2 - > B6)时,新微(B6)成为新选择的选项。

 constructor(props) {
  super(props);
   this.state = {
    value: '',
  };

   this.handleChange = this.handleChange.bind(this);
}

handleChange(e) {
  const { value } = e.target;
   this.setState({
      value: value
   });
 }

 render() {
  return (
    <ul className="menuitems">
      <li>
        <Vitamins data={this.props.users} />
      </li>
      <li>
         <Minerals data={this.props.users} />
       </li>
    </ul>
  )
}

这是Vitamins.js(我也有Minerals.js,AminoAcids.js等),我试图在地图上找到&#34;维生素&#34;我的res.json对象中的数组,并在选择下拉列表中拉出每个名称。

  renderData() {
    const vitamins = this.props.data;
    console.log("the data", vitamins);
    return vitamins.map((micro, index) => {
     return (
       <option value={micro.value} key={index}>{micro.name}</option>
     )
   })
 }

  render() {
   return (
    <form>
      <select value={this.props.value} onChange={this.handleChange}>
        <option value="" selected>--Vitamins--</option>
        {this.renderData()}
      </select>
    </form>
  )
 }

renderData()中的console.log最初不显示任何内容,但在componentDidMount()之后显示此TWICE

 the data {vitamins: Array(6), minerals: Array(2), aminoacids: Array(1), antioxidants: Array(2), omegas: Array(1)}

修改

我接受了一些建议,并尝试应用它。

这个有效,我在每个儿童成分(维生素,矿物质等)中宣布了状态

 state = {users: []};

 componentDidMount() {
   fetch('/users')
    .then(res => res.json())
    .then(users => {
      this.setState({
        users: users.vitamins
      });
    })
  }

 renderData() {
   const vitamins = this.state.users;
   return vitamins.map((micro, index) => {
   return (
      <option value={micro.value} key={index}>{micro.name}</option>
    )
  })
}

但是,我不想在每个组件中继续提取。我尝试在父MenuItems中声明状态,并按照建议在数据道具中传递{this.state.users.vitamins}。

(MenuItems.js)

state = {users: []};

componentDidMount() {
  fetch('/users')
    .then(res => res.json())
    .then(users => {
     this.setState({
       users
     });
   })
 }

render() {
  return (
    <ul className="menuitems">
      <li>
        <Vitamins data={this.state.users.vitamins} />
      </li>
    </ul>
 )
}

(Vitamins.js)

 renderData() {
   const vitamins = this.props.data;
   return vitamins.map((micro, index) => {
     return (
       <option value={micro.value} key={index}>{micro.name}</option>
     )
   })
 }

但是,我得到&#34; TypeError:无法读取属性&#39; map&#39;未定义&#34;当我这样做时。

如果我做&#34; const {vitamin} = this.props.data&#34;,我得到&#34; TypeError:无法读取属性&#39;维生素&#39;未定义&#34;。

那么我如何在父级获取,并将我需要的唯一数组传递给data =?

1 个答案:

答案 0 :(得分:1)

您目前只提取用户。在vitamin.js中,您尝试从this.props.data获取数据,这将提供您正在处理数组的信息,如控制台日志中所示。你需要&#34;拆分&#34;您的数据才能获取。

this.setState({ users: users.vitamins)} 
例如

(我不知道您的生态系统,因此您尝试获取的任何内容都需要在setState事件中关联,否则您只需传递没有数据定义的数据)。

正如已经在评论部分发布的那样,您还可以尝试在将数据传递给组件时将其拆分:

    <Vitamins data={this.props.users.vitamins}

它基本相同,你拿用户并获取维生素数据。无论何时想要映射数组,都必须打开&#34;打开&#34;它了。

这是一个基本的例子,你通常会这样做:

  .then(response => response.json())
  .then(data => data.users.your-data-you-want-to-fetch.map((x) => {

    this.setState({
      vitamin: x.name,
      id: x.id,
      })

}))

然后可以访问您的道具数据

data.vitamin / data.id。

问候!