Как отображать нужные мне компоненты

138
15 ноября 2018, 23:50

Есть компонент TaskList в нем отрисовывается несколько Task . Задача - отрисовывать по клику разные обьекты массива. Что мне закидывать в state? Правильно понимаю что как раз массив?И как его изменить в таком случае?

собственно вот код

компонент Task

class Task extends React.Component {
  render() {
    const { name, description, group } = this.props;
    return (
      <div>
        {statementsData.map(elem => (
          <article
            style={{
              border: "2px solid blue ",
              padding: "30px",
              margin: "3px"
            }}
            key={elem.id}
          >
            <div>{elem.name}</div>
            <div>{elem.description}</div>
            <div>{elem.group}</div>
          </article>
        ))}
      </div>
    );
  }
}
Task.defaultProps = {
  group: "Execute"
};
export const statementsData = [
  {
    id: 0,
    name: "first",
    description:
      "нализируйте день: выясняйте, что помешало выполнить все пункты вашего листа задач на день. По итогам решайт",
    group: "Execute"
  },
  {
    id: 1,
    name: "second",
    description:
      "Выделяйте приоритетные дела —  задачи, позволяющие достигать глобальных целей.",
    group: "Execute"
  },
  {
    id: 2,
    name: "third",
    description:
      "ййййцу йцу йцйцв йцв бальных целей. Ответьте на вопрос, насколько",
    group: "Performens"
  },
  {
    id: 3,
    name: "thirdqq",
    description: "о важная и срочная каждая задача и нельзя ли ",
    group: "Done"
  }
];
export default Task;

компонент TaskList

import React, { Component } from "react";
import Task from "../task/task";
import { statementsData } from "../task/task";
class TaskList extends Component {
  constructor(props) {
    super(props);
    this.state = {
       statementsData
    };
    console.log(this.state);
    console.log(statementsData);
  }
  showAlert() {
    alert("Im an alert");
  }
  showAlertq() {
    this.setState({
        this.statementsData = []
    });
  }
  render() {
    return (
      <React.Fragment>
        <button onClick={this.showAlertq.bind(this)}>отрисовать все</button>
        <button onClick={this.showAlert}>отрисовать Execute</button>
        <button onClick={this.showAlert}>отрисовать Performed</button>
        <button onClick={this.showAlert}>отрисовать Done</button>
        <h1>hello Tasklist</h1>
        <Task />
      </React.Fragment>
    );
  }
}
export default TaskList;

Answer 1

Логично, что в состоянии компонента Tasks точно должно быть свойство, отвечающее за группу элементов, которые нужно отрендерить:

this.state = {
    group: null/"Performed"/"Execute"...
}

Далее нам нужны данные. Для этого можно (нужно) создать массив объектов, которые будут пропсами для компонента Task (но я дивом сделаю ниже, лень писать)

taskProps = [
    {
        title: "Title 1",
        content: "Lorem ipsum",
        group: "Performed"
    },
    {
        title: "Title 2",
        content: "Lorem ipsum dolor",
        group: "Execute"
    },
    ...
]

По нажатию на кнопку будем менять состояние state.group

<button onClick={() => this.changeGroup("All")}>отрисовать все</button>
<button onClick={() => this.changeGroup("Execute")}>отрисовать Execute</button>
<button onClick={() => this.changeGroup("Performed")}>отрисовать Performed</button>
<button onClick={() => this.changeGroup("Done")}>отрисовать Done</button>

И сам changeGroup:

changeGroup(group) {
    this.setState({
        group: group
    })
}

Теперь компоненты надо как-то фильтровать. Лучший способ - использовать метод .filter(). Он возьмет массив и выберет из него только то, что соответствует нашему условию:

this.taskProps.filter(item => item.group === this.state.group || this.state.group === null)

Теперь у нас есть отфильтрованный массив. Осталось передать его объекты в компонент Task в качестве проспсов, но в нашем случае понадобится еще один метод .map

taskProps.filter(item => item.group === this.state.group || this.state.group === null).map(item => (
    <div style={{ background: "gray", margin: "4px" }}> // тут типа Task
        <h2>title: {item.title}</h2>
        <span>content: {item.content}</span>
        <h3>group: {item.group}</h3>
    </div>
))}

Вот и все. Рабочий пример залил на pen для удобства

READ ALSO
Альтернатива кода JQuery на чистом JavaScript

Альтернатива кода JQuery на чистом JavaScript

ЗдравстуйтеЕсть рабочий скрипт написанный на JQuery высветляющий значение "No Results" при введении в input несуществующего значения в таблице("Живой...

158
JS/JQUERY складывать все теги li и сделать средняю арифметику

JS/JQUERY складывать все теги li и сделать средняю арифметику

надо с помощью js делать вот такую операцию (45+100+56+23)/4

154
Альтернатива socket.io

Альтернатива socket.io

У нас фронт на angular и бэк на nodejs

140
Передать пароль при подключении по websocket

Передать пароль при подключении по websocket

Рефакторим один легаси проектВ нем таким вот образом устанавливается вэбсокет соединение между node

155