2 votes

Impossible de rendre le composant lors de l'utilisation d'un réducteur

J'utilise React-Redux pour créer une application de calendrier qui stocke les tâches de jardinage par mois. Lorsque j'utilise un reducer pour stocker les objets 'tâches', je ne parviens pas à les rendre dans le calendrier, bien que je ne reçoive aucune erreur de la console. Lorsque je passe le nom de la tâche à l'aide d'une chaîne de caractères, le rendu se fait correctement.

J'ai principalement débogué en enregistrant la console à chaque point pour vérifier que les données transmises ne sont pas indéfinies et qu'elles sont du bon type. Tout dans mon application est conforme à ce que j'attendais, et rien ne semble aller de travers, sauf qu'il n'y a pas de rendu.

Le présent n'est pas rend les tâches dans le calendrier, mais ne produit pas d'erreurs :

  render() {
    return (
      <ul className="task-container">
          { this.props.taskTypes.map(task => task.name).forEach(taskName => this.renderTask(taskName)) }
      </ul>
    );
  };

Ce code fonctionne (les tâches sont affichées dans le calendrier comme prévu) :

  render() {
    return (
      <ul className="task-container">
        { this.renderTask("Harvest") }
      </ul>
    );
  };

Voici mon fichier de réduction (task-types.js) :

export default function() {
  return [
    { name: 'Sow Indoors' },
    { name: 'Sow Outside' },
    { name: 'Plant Outside' },
    { name: 'Harvest' },
  ];
}

Voici le fichier conteneur dans son intégralité (TaskGroup.js) :

class TaskGroup extends Component {
  constructor(props) {
    super(props);
    this.checkAgainstMonthAndType = this.checkAgainstMonthAndType.bind(this);
    this.taskTypeIsUsed = this.taskTypeIsUsed.bind(this);
    this.taskHasItems = this.taskHasItems.bind(this);
    this.renderTaskGroup = this.renderTaskGroup.bind(this);
    this.renderTask = this.renderTask.bind(this);
    this.renderTaskItems = this.renderTaskItems.bind(this);
  }

  checkAgainstMonthAndType(list, givenMonth, givenType) {
    return list.some(item => item.month === givenMonth && item.type === givenType);
  }

  taskTypeIsUsed(list, givenMonth, givenType) {
    return list.some(item => this.checkAgainstMonthAndType(item.tasks, givenMonth, givenType));
  };

  taskHasItems(list, givenMonth, givenType) {
    return this.checkAgainstMonthAndType(list, givenMonth, givenType);
  };

  renderTask(taskType) {
    const taskClass = taskType.toLowerCase().replace(" ", "-"); // Sow Indoors -> sow-indoors

    if( this.taskTypeIsUsed(this.props.data, this.props.thisMonth, taskType) ) {
      return (
        <li key={`key-${taskClass}`} className={`task task--${taskClass}`}>
          <h3 className={`task__title task__title--${taskClass}`}>{taskType}</h3>
          <ul className="task__item-list">
            {this.renderTaskItems(taskType)}
          </ul>
        </li>
      );
    }
  };

  renderTaskItems(taskType) {
    return this.props.data
      .filter(item => this.taskHasItems(item.tasks, this.props.thisMonth, taskType))
      .map(item =>
        <Task key={`task-${item.name}`} variety={item.variety} name={item.name} />
      );
  };

  render() {
    return (
      <ul className="task-container">
        {this.renderTask("Sow Indoors")}
      </ul>
    );
  };

}

function mapStateToProps(state) {
  return {
    taskTypes: state.taskTypes,
    data: state.data
  }
}

TaskGroup.propTypes = {
  thisMonth: PropTypes.string.isRequired,
  taskTypes: PropTypes.array.isRequired,
  data: PropTypes.array.isRequired,
};

export default connect(mapStateToProps)(TaskGroup);

L'application calendrier lit les données API, chaque plante étant un objet dans ce format :

{
      "id": 0,
      "name": "Peas",
      "variety": "Sugarsnap",
      "tasks": [
        {
          "type": "Sow Indoors",
          "month": "Feb"
        },
        {
          "type": "Plant Outside",
          "month": "Apr"
        },
        {
          "type": "Harvest",
          "month": "May"
        }
      ]
    }

4voto

mersocarlin Points 5415

forEach ne renvoie rien. Utilisez seulement map au lieu de cela.

render() {
  return (
    <ul className="task-container">
      {this.props.taskTypes.map(task => this.renderTask(task.name)}
    </ul>
  )
}

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X