web-dev-qa-db-fra.com

Je ne comprends pas pourquoi les composants avec 'connect ()' sont dynamiques dans reag

Ma question est juste comme le titre. 

Disons que j'ai écrit le code suivant.

class TODOList extends Component {  
  render() {
    const {todos, onClick} = this.props;
    return (
      <ul>
            {todos.map(todo =>
                <Todo 
                    key={todo.id}
                    onClick={onClick}
                    {...todo}
                />
             )}
      </ul>
    );
  }
}


const mapStateToProps = (state) => {  
  return {
    todos: state.todos
  }
}


const mapDispatchToProps = (dispatch) => {  
    return {
        onClick(data){
          dispatch(complete(data)) 
        }
    }
}


export default connect(mapStateToProps,mapDispatchToProps)(TODOList); 

Maintenant, après la dernière ligne, ce code exportera le composant TODOList avec l'état comme accessoire. Ce n'est pas qu'il contienne un état, mais juste un état reçu et les aura comme «accessoires», tout comme le nom de la méthode «mapStateToProps».

Dans le post moyen ( https://medium.com/@dan_abramov/smart-and-dumb-components-7ca2f9a7c7d0 ) écrit par Dan Abramov, le composant conteneur traite les données en tant qu'état et la propriété de présentation en tant qu'accessoires. N'est-ce pas une composante de présentation qui traite les données comme des accessoires? Je suis coincé avec l'idée que le bon conteneur devrait être un comme ci-dessous.

class CommentList extends React.Component {
  this.state = { comments: [] };

  componentDidMount() {
    fetchSomeComments(comments =>
      this.setState({ comments: comments }));
  }
  render() {
    return (
      <ul>
        {this.state.comments.map(c => (
          <li>{c.body}—{c.author}</li>
        ))}
      </ul>
    );
  }
}

Je ne suis pas sûr de savoir pourquoi react-redux a appelé l'API 'mapStateToProps', alors que j'essayais de créer un composant conteneur 'avec état' (ne traitant pas les données par propriété)

9
Rhee

Tout d'abord, ces directives ne font pas partie de la Bible.
vous devriez écrire un code facile à raisonner pour YOU et votre TEAM

Je pense qu'il vous manque quelque chose, un conteneur redux est différent d'un conteneur réagit.
Je veux dire, connect va créer le conteneur pour vous, cela ne signifie pas que le composant encapsulé est un conteneur. 

En principe, vous pouvez exporter les deux versions à partir du même fichier, le conteneur (version connectée) et la version de présentation (la version non connectée). 

Le nom de la fonction et l'argument de mapStateToProps sont une autre chose qui décourage généralement les gens.
Je préfère le nom mapStoreToProps comme dans 

mappez le magasin redux aux accessoires du composant. 

le nom state peut être déroutant lorsque nous sommes dans le contexte de react.

Modifier
Pour faire suite à votre commentaire: 

Je ne savais pas que ces deux-là étaient réellement différents. Pourriez-vous s'il vous plaît me parler de plus de détails

Ils sont différents dans la manière dont connect crée un "conteneur" pour vous. 

connect est un composant d'ordre élevé qui crée le composant de conteneur pour nous avec toute la logique d'abonnement + des fonctions permettant de transmettre des portions du magasin et des créateurs d'action à ses enfants en tant qu'accessoires (mapStateToProps & mapDispatchToProps).

Un conteneur "normal" fait généralement référence à un composant que vous écrivez à la main. Souvent, il ne traite pas de l'apparence des choses mais de certaines logiques de l'application.

Quant aux autres commentaires comme

Le centre de contrôle connect de react-redux n’injecte que les propriétés que vous pouvez demander à votre composant. Il retourne un nouveau composant encapsulé autour de votre composant afin qu'il puisse le mettre à jour chaque fois que l'état qui vous intéresse dans le magasin redux est modifié.

Comme je l'ai mentionné ci-dessus, cela est partiellement vrai. Il ne s'agit pas simplement d'injecter les propriétés dans notre composant, de s'abonner au magasin, de le récupérer à partir de la variable Provider (via context) et de le faire avec l'optimisation à l'esprit, afin que nous n'ayons pas à le faire nous-mêmes. 

Je ne sais pas comment mapStateToProps peut confondre quelqu'un. Nous parlons d'une bibliothèque de gestion d'état

J'ai vu des développeurs qui ont mal compris cela parce que react a un state et redux a un store (du moins c'est comme cela qu'il a été appelé dans la plupart des tutoriels et documentations).
Cela peut être déroutant pour certaines personnes qui sont nouvelles à react ou redux

Edit 2

C'était un peu déroutant en raison de la phrase "cela ne signifie pas que le composant encapsulé est un conteneur". Pourquoi le composant encapsulé n'est-il pas un conteneur? Un composant créé par connect n'est-il pas aussi un conteneur?

Je veux dire que le composant encapsulé que vous avez écrit ne doit pas obligatoirement être un conteneur.
Vous pouvez connecter un composant "Présentation": 

const Link = ({ active, children, onClick }) => {
  if (active) {
    return <span>{children}</span>
  }

  return (
    <a
      href=""
      onClick={e => {
        e.preventDefault()
        onClick()
      }}
    >
      {children}
    </a>
  )
}

// ...
export default connect(mapState, mapDispatch)(Link)
10
Sagiv b.g

mapStateToProps sera appelé lorsque les données du magasin seront modifiées. Il passera l'objet renvoyé en tant que nouveaux accessoires pour le composant. Cela n'affectera pas l'état du composant. Si vous souhaitez définir un nouvel état après que le composant ait obtenu ses nouveaux accessoires, vous devez utiliser une autre méthode de cycle de vie: static getDerivedStateFromProps (dans les versions antérieures de react componentWillRecieveProps). L'objet renvoyé par static getDerivedStateFromProps sera votre nouvel état.

https://reactjs.org/docs/state-and-lifecycle.html#adding-lifecycle-methods-to-a-class

connect() connectera votre composant au magasin redux. Sans la fonction de connexion (bien sûr), votre mapStateToProps ne fonctionnera pas.

Je ne suis pas sûr de savoir pourquoi react-redux a nommé l'API 'mapStateToProps'

Nous parlons de l'état du magasin :)

2
messerbill

L'objectif principal est d'intégrer de manière transparente la gestion des états de Redux dans l'application React. Redux tourne autour du magasin où tout l'état existe. Il n’existe aucun moyen de modifier directement le magasin, sauf par le biais de réducteurs recevant des actions des créateurs d’action. Pour que cela se produise, il faut qu’une action soit envoyée par le créateur d’action.

La fonction connect() connecte directement nos composants au magasin Redux en prenant l’état dans le magasin Redux et en le mappant dans une prop.

C'est le pouvoir de Redux et c'est pourquoi nous l'utilisons.

Disons que vous construisez un composant appelé LaundryList et que vous souhaitez qu'il affiche une liste de blanchisserie. Une fois que vous avez câblé la Provider dans votre composant "parent", je le mets entre guillemets car techniquement, Provider est un composant et devient donc le parent.

Vous pouvez ensuite importer la fonction connect() à partir de react-redux et la transmettre à mapStateToProps afin d’obtenir cette liste de blanchisserie du magasin Redux dans votre composant LaundryList.

Maintenant que vous avez votre liste de draps à l'intérieur du composant LaundryList, vous pouvez commencer à vous concentrer sur la construction d'une liste d'éléments, comme ceci:

class LaundryList extends Component {
  render() {
    console.log(this.props.linens);
    return <div>LaundryList</div>;
  }
}

Cela contient la liste des objets linens et pour chaque liste des draps à l'intérieur, nous allons retourner un jsx qui va représenter ce lin sur ma liste.

De retour dans mon composant de liste de blanchisserie, j'ajouterai une méthode d'assistance à l'intérieur du composant de liste de blanchisserie appelée render list, comme suit:

class LaundryList extends Component {
  renderList() {

  }

  render() {
    return <div>LaundryList</div>;
  }
}

Donc, le but de cette méthode d'assistance est de prendre la liste des draps, de les cartographier et de renvoyer un gros bloc de jsx comme ceci:

class LaundryList extends Component {
  renderList() {
    return this.props.linens.map((linen) => {
       return (

       );
    });
  }

  render() {
    return <div>LaundryList</div>;
  }
}
0
Daniel