bugfix> javascript > 投稿

さまざまな種類の微量栄養素(ビタミン、ミネラル、酸化防止剤、アミノ酸、およびオメガ)のために、オブジェクト内に複数の配列があります。私はそれぞれが <option> として渡されることを望みます独自のタイプを表示する独自のドロップダウンメニュー内(例:ビタミン:ビタミンB2、B6、B5など)

私のコンソールは、データが正常に取得されたことを示しています。

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

しかし、オプションをレンダリングしようとしているVitamins.jsに到達すると、「TypeError:vitamins.map is a function not」と表示されます。

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に対して状態が宣言されています。 (「ユーザー」は今のところ意味論的な意味を持たないことを知っています。それを変更します。最初に機能していない理由を理解しようとしています。)

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

これは、Home.jsから1レベル下のMenuitems.jsであり、ユーザーが新しいマイクロ(Vitamin 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などもあります)で、res.jsonオブジェクトの "vitamins"配列にマップし、select内の各名前を取得しようとしています。落ちる。

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

しかし、これを行うと「TypeError:undefinedのプロパティ 'map'を読み取れません」というメッセージが表示されます。

「const {vitamins} = this.props.data」を実行すると、「TypeError:未定義のプロパティ 'vitamins'を読み取れません」が表示されます。

それで、親レベルでどのようにフェッチし、必要な唯一の配列をdata =に渡すのですか?

回答 1 件
  • 現在、ユーザーのみを取得しています。 vitamins.jsでは、this.props.dataからデータを取得しようとします。これにより、コンソールログに表示されているように、配列を扱っている情報が得られます。データを取得するには、データを「分割」する必要があります。

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

    たとえば(私はあなたのエコシステムを知らないので、フェッチしようとしているものはすべてsetStateイベントに関連付ける必要があります。そうでなければ、データ定義なしでデータを渡すだけです)

    コメントセクションに既に投稿されているように、データをコンポーネントに渡すときに分割することもできます。

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

    基本的には同じで、ユーザーを取得してビタミンデータを取得します。配列をマップしたいときはいつでも、それを「開く」必要があります。

    これが基本的な例であり、通常どのようにそれを行うかです:

     .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は、小道具データにアクセスできるようになります。

    ご挨拶!

あなたの答え