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.