web-dev-qa-db-fra.com

Filtrer une liste avec React

Hmm, je ne vois pas mon omission, mais je reçois une page vierge avec une erreur de console disant:

Users.js:9 Uncaught TypeError: Cannot read property 'filter' of undefined
    at Users.render (Users.js:9)

Apparemment, j'utilise mal 'filter ()'. J'ai regardé autour de moi, mais je n'ai rien trouvé en rapport avec 'React'. Quelqu'un peut-il aider? Voici les fichiers:

<!doctype html>
<html lang="en">
  <head>
    <meta charset="utf-8">
    <title>React App</title>
  </head>
  <body>
    <div id="root"></div>
  </body>
</html>

index.js

import React from 'react';
import ReactDOM from 'react-dom';
import Users from './Users';

ReactDOM.render(
  <Users list={[
    { name: 'Tyler', friend: true },
    { name: 'Ryan', friend: true },
    { name: 'Michael', friend: false },
    { name: 'Mikenzie', friend: false },
    { name: 'Jessica', friend: true },
    { name: 'Dan', friend: false }
    ]}
  />,
  document.getElementById('root')
);

Users.js

import React from 'react';

class Users extends React.Component {
  render() {
    return (
      <div>
        <h1>Friends:</h1>
        <ul>
          {this.props.list.friend.filter(function (friend) {
            return <li>{friend[0] === 'true'}</li>
        })}
        </ul>

        <hr />

        <h1>Non Friends:</h1>
        <ul>
          {this.props.list.friend.filter(function (nonFriend) {
            return <li>{nonFriend[0] === 'false'}</li>
          })}
        </ul>
      </div>
    );
  }
}

export default Users;
7
Ron Allen Smith

D'accord, ressemble à "Users.js" devrait être:

import React from 'react';

class Users extends React.Component {
  render() {
    let friends = this.props.list.filter( function (user) {
      return user.friend === true
    });

    let nonFriends = this.props.list.filter( function (user) {
      return user.friend !== true
    });

    return (
      <div>
        <h1>Friends:</h1>
        <ul>
          {friends.map(function (user) {
            return <li key={user.name}>{user.name}</li>
          })}
        </ul>
        <h1>Non Friends:</h1>
        <ul>
          {nonFriends.map(function (user) {
            return <li key={user.name}>{user.name}</li>
          })}
        </ul>
      </div>
    );
  }
}

export default Users;

Ou même ceci:

import React from 'react';

class Users extends React.Component {
  render() {
    return (
      <div>
        <h1>Friends:</h1>
        <ul>
          {this.props.list.filter(function (user) { // filter first for friends
            return user.friend === true // returns a new array
          }).map(function (user) {  // map the new array to list items
            return <li key={user.name}>{user.name}</li> // don't forget unique key for each item
          })}
        </ul>

        <hr />

        <h1>Non Friends:</h1>
        <ul>
          {this.props.list.filter(function (user) { // filter first for non-friends
            return user.friend !== true // returns a new array
          }).map(function (user) {  //map the new array to list items
            return <li key={user.name}>{user.name}</li> // don't forget unique key for each item
          })}
        </ul>
      </div>
    );
  }
}

export default Users;
7
Ron Allen Smith

Vous appelez .friend sur la liste elle-même lorsqu'il s'agit d'une propriété de chaque objet de votre tableau. Vous utilisez également .filter, mais je ne pense pas que vous l'utilisiez correctement ici. .filter renverra un tableau avec certains éléments où la fonction passée retourne une valeur véridique. Voici comment vous pouvez le faire avec .filter:

var nonFriends = this.props.list.filter(function (user) {
  return !user.friend;
});

var friends = this.props.list.filter(function (user) {
  return user.friend;
});

return (
  <div>
    <h1>Friends:</h1>
    <ul>{ friends }</ul>
    <h1>Non Friends:</h1>
    <ul>{ nonFriends }</ul>
  </div>
);

Vous pouvez également faire un .forEach pour 1 passer à travers le tableau si le tableau est grand:

var nonFriends = [], friends = [];

this.props.list.forEach(function (user) {
  if (user.friend) {
    friends.Push(user);
  } else {
    nonFriends.Push(user);
  }
});

// now render friends and nonFriends
4
Vinay

Je pense que vous essayez de filtrer l'attribut et non la liste. Essayez de changer cela:

this.props.list.friend.filter

pour ça:

this.props.list.filter
2
Ariel Jr

Je ferais quelque chose comme ça à la place qui est un peu plus simple

{this.props.list.map(function (person, i) {
  {return person.friend
    ?(<li key={i}>{person.name}</li>)
    : null
  }
})}
  1. Vous parcourez la liste elle-même, pas un élément de la liste, c'est pourquoi this.props.list.friend.filter n'a pas fonctionné.
  2. J'utiliserais la carte car vous ne filtrez pas réellement les listes dans ce cas. Si vous le souhaitez, vous pouvez filtrer la liste au préalable en amis et non amis et cartographier les éléments qui seraient en fait plus simples à voir pour un autre ingénieur.
  3. React veut keys dans le balisage pour les éléments itérés créés. C'est ainsi que React crée les relations entre les composants de l'arbre d'état.
2
oftenfrequent