J'essayais de compter les tâches terminées et la logique devrait être correcte je crois, mais il semble que this.setState ({})
ne répond pas / atteint du tout, il ne fait rien aux données 'qtySelected' dans this.state ({})
puisque console.log ('ts')
n'a pas eu de résultat dans la console. Tout le monde sait pourquoi, c'est peut-être un problème de cycle de vie de réaction?
export class Main extends Component { constructor(pros) { super(pros) this.state = { tasks: [ { id: 1, content: "Sara's doctor and vaccine", due: '2020-08-29', completed: false }, { id: 2, content: "Trash bags / facial masks / child allowance", due: '2020-08-28', completed: false }, { id: 3, content: "Apply for Portugal nationality", due: '2020-09-31', completed: false }, { id: 4, content: "My registeration card", due: '2020-09-28', completed: false }, { id: 5, content: "contact ADEM", due: '2020-12-31', completed: false }, { id: 6, content: "Pay loan", due: '2020-09-03', completed: true } ], qtySelected: 0 } } componentDidMount() { this.countSelected = () => { console.log('ts') let tasksCompleted = this.state.tasks.filter(task => { return task.completed === true }) this.setState({ qtySelected: tasksCompleted.length }) } } render() { return ( <div> <table> <tfoot> <tr> <td style={{ whiteSpace: "nowrap" }}>{this.state.qtySelected} selected</td> </tr> </tfoot> </table> </div> ) } }
3 Réponses :
Vous n'appelez la fonction this.countSelected
nulle part. Dans tous les cas, les données que vous pouvez calculer directement à partir de l'état actuel ne doivent pas être stockées dans l'état.
export class Main extends Component { constructor(props) { super(props); this.state = { tasks: [ // ... ], }; } render() { const selectedCount = this.state.tasks.filter((task) => task.completed).length; return ( <div> <table> <tfoot> <tr> <td style={{ whiteSpace: "nowrap" }}>{selectedCount} selected</td> </tr> </tfoot> </table> </div> ); } }
merci pour la solution, cela a fonctionné. Mais vous avez dit «ne devrait pas», pourquoi? C'est juste une mauvaise pratique mais fonctionne toujours, ou c'est tout simplement faux et ne fonctionnera pas (j'ai essayé de garder l'état `` qtySelected '' comme ce que Luke Storry a suggéré mais cela ne fonctionnait que lorsqu'il était chargé et ne serait pas mis à jour lorsque j'ai coché d'autres cases, c'est cela a été causé par l'ajout de ce nouvel état supplémentaire qtySeleceted?)
C'est juste une mauvaise pratique - cela fonctionnera toujours, mais chaque fois que vous utiliserez setState
, le composant sera de nouveau rendu - si vous créez simplement un nouvel état basé uniquement sur l'ancien état, vous n'avez pas besoin pour le rendre deux fois - stockez simplement la valeur calculée dans une variable comme dans cette réponse
Rien n'exécute cette fonction.countSelected. Supprimez donc la fonction ou rendez-la externe à componentDidMount et appelez-la depuis componentDidMount.
En fait, vous n'exécutez rien dans le componentDidMount
- vous définissez simplement une nouvelle fonction this.countSelected
.
En utilisant également la version de rappel de setState
est la meilleure pratique a> lorsque vous utilisez une valeur d'état précédente pour mettre à jour l'état.
Dans l'ensemble, vous pouvez l'utiliser comme nouveau componentDidMount
et cela devrait fonctionner comme prévu:
<td style={{ whiteSpace: "nowrap" }}> {this.state.tasks.filter(task => task.completed).length} selected </td>
Alternativement, vous devriez probablement simplement utiliser cette valeur calculée directement au lieu de forcer un deuxième rendu, car il n'a pas vraiment besoin d'être une variable d'état séparée .
componentDidMount() { this.setState(state => ({ qtySelected: state.tasks.filter(task => task.completed).length })) }
merci pour votre explication, mais la première façon a toujours un problème: cela n'a fonctionné qu'une seule fois lorsque vous venez de charger la page, et après si vous cochez d'autres cases, le numéro ne se met pas à jour et reste à '1' sélectionné. Le second fonctionne sans problème cependant.
Oui, c'est la définition exacte de componentDidMount
. Il fonctionnera une fois, sur le montage. Si vous voulez qu'il exécute tous les rendus, placez-le dans la fonction de rendu.