Je développe une nouvelle application en utilisant la nouvelle API React Context au lieu de Redux, et avant, avec Redux
, lorsque j'avais besoin d'obtenir une liste d'utilisateurs par exemple, j'appelle simplement componentDidMount
mon action, mais maintenant avec React Context, mes actions vivent à l'intérieur mon consommateur qui est à l'intérieur de ma fonction de rendu, ce qui signifie que chaque fois que ma fonction de rendu est appelée, elle appellera mon action pour obtenir ma liste d'utilisateurs et ce n'est pas bon car je vais faire beaucoup de requêtes inutiles.
Alors, comment puis-je appeler une seule fois mon action, comme dans componentDidMount
au lieu d'appeler dans render?
Juste pour illustrer, regardez ce code:
Supposons que j'emballe tout mon Providers
dans un seul composant, comme ceci:
import React from 'react';
import UserProvider from './UserProvider';
import PostProvider from './PostProvider';
export default class Provider extends React.Component {
render(){
return(
<UserProvider>
<PostProvider>
{this.props.children}
</PostProvider>
</UserProvider>
)
}
}
Ensuite, je mets ce composant Provider enveloppant toute mon application, comme ceci:
import React from 'react';
import Provider from './providers/Provider';
import { Router } from './Router';
export default class App extends React.Component {
render() {
const Component = Router();
return(
<Provider>
<Component />
</Provider>
)
}
}
Maintenant, à la vue de mes utilisateurs par exemple, ce sera quelque chose comme ceci:
import React from 'react';
import UserContext from '../contexts/UserContext';
export default class Users extends React.Component {
render(){
return(
<UserContext.Consumer>
{({getUsers, users}) => {
getUsers();
return(
<h1>Users</h1>
<ul>
{users.map(user) => (
<li>{user.name}</li>
)}
</ul>
)
}}
</UserContext.Consumer>
)
}
}
Ce que je veux, c'est ceci:
import React from 'react';
import UserContext from '../contexts/UserContext';
export default class Users extends React.Component {
componentDidMount(){
this.props.getUsers();
}
render(){
return(
<UserContext.Consumer>
{({users}) => {
getUsers();
return(
<h1>Users</h1>
<ul>
{users.map(user) => (
<li>{user.name}</li>
)}
</ul>
)
}}
</UserContext.Consumer>
)
}
}
Mais bien sûr, l'exemple ci-dessus ne fonctionne pas car les getUsers
accessoires de vue de mes utilisateurs ne sont pas présents. Quelle est la bonne façon de procéder si cela est possible?
la source
this.context
avec plusieurs contextes dans le même composant? Supposons que j'ai un composant qui a besoin d'accéder à UserContext et PostContext, comment gérer cela? Ce que je peux voir, c'est créer un contexte mélangeant les deux, mais c'est la seule ou la meilleure solution pour cela?Ok, j'ai trouvé un moyen de le faire avec une limitation. Avec la
with-context
bibliothèque, j'ai réussi à insérer toutes mes données de consommation dans mes accessoires de composants.Mais, pour insérer plus d'un consommateur dans le même composant est compliqué à faire, il faut créer des consommateurs mixtes avec cette bibliothèque, ce qui rend le code pas élégant et non productif.
Le lien vers cette bibliothèque: https://github.com/SunHuawei/with-context
EDIT: En fait, vous n'avez pas besoin d'utiliser l'API multi-contexte qui
with-context
fournit, en fait, vous pouvez utiliser l'API simple et créer un décorateur pour chacun de vos contextes et si vous souhaitez utiliser plus d'un consommateur dans votre composant, il suffit déclarez au-dessus de votre classe autant de décorateurs que vous le souhaitez!la source
Pour ma part, il suffisait d'ajouter
.bind(this)
à l'événement. Voici à quoi ressemble mon composant.// Stores File class RootStore { //...States, etc } const myRootContext = React.createContext(new RootStore()) export default myRootContext; // In Component class MyComp extends Component { static contextType = myRootContext; doSomething() { console.log() } render() { return <button onClick={this.doSomething.bind(this)}></button> } }
la source
Vous devez passer le contexte dans le composant parent supérieur pour obtenir l'accès en tant qu'accessoire dans child.
la source