I
I
Ilya2019-10-17 13:30:53
React
Ilya, 2019-10-17 13:30:53

How to display part of the list of topics in a different way?

I have a list of topics with subtopics. I get this data from the server and insert it into the state:

useEffect(() => {
  axios
    .get('http://sidorchik.ru/reshuege/api/')
    .then(response => response.data)
    .then(data =>
      data.map(topic => ({
        id: topic.id,
        title: topic.title,
        part: topic.part,
        subtopics: topic.subtopics.map(subtopic => ({
          id: subtopic.id,
          title: subtopic.title,
          amount: subtopic.amount,
          checked: true
        })),
        value: 0,
        checked: false
      }))
    )
    .then(data => setTopicsList(data))
    .catch(error => console.log(error));
}, []);

I group topics by parts (Test, Expanded or Additional):
const parted = topicsList.reduce(
    (acc, { id, part, title, value, checked, subtopics }) => {
        acc[part] = acc[part] || [];
        acc[part].push({
            id,
            title,
            value,
            checked,
            subtopics
        });
        return acc;
    },
    {}
);

add markup:
return Object.entries(parted).map(([part, topics], partI) => {
    let partName;
    switch (part) {
        case 'test':
            partName = (
                <div className="ConstructorForm-Row ConstructorForm-Row_label">
                    <div className="ConstructorForm-Topic">
                        Тестовая часть
                    </div>
                </div>
            );
            break;
        case 'detailed':
            partName = (
                <div className="ConstructorForm-Row ConstructorForm-Row_label">
                    <div className="ConstructorForm-Topic">
                        Развернутая часть
                    </div>
                </div>
            );
            break;
        case 'extra':
            partName = (
                <div className="ConstructorForm-Row ConstructorForm-Row_label">
                    <div
                        className="ConstructorForm-Topic Link Link_pseudo Link_wrap"
                        onClick={() => handleExtraPartNameClick()}
                    >
                        <u className="Link-U Link_pseudo-U Link_wrap-U">
                            Задания, не входящие в ЕГЭ этого года
                        </u>
                    </div>
                </div>
            );
            break;
        default:
            partName = null;
            break;
    }

    return (
        <div class="ConstructorForm-Part" key={partI}>
            {partName}
            {(part !== 'extra' ||
                (part === 'extra' && extraTopics)) &&
                topics.map(
                    (
                        { id, title, value, checked, subtopics },
                        i
                    ) => (
                        <div
                            className="ConstructorForm-Row"
                            key={'topic' + partI + i}
                        >

and output:
return (
    {getContentByParts()}
);

Two questions.
1. Is it better to immediately pass a list grouped in parts to the state?
2. How to deal with the extra part? Its title needs to be displayed differently and the content hidden. I did it now, but it seems to me that the code is not very good. Tell me please.
If you point out what else to refactor, I will be grateful.
Component on Github

Answer the question

In order to leave comments, you need to log in

1 answer(s)
G
grinat, 2019-10-17
@grinat

getContentByParts()
Components were specially invented, and others can be inserted into some components, and so on ad infinitum.

Didn't find what you were looking for?

Ask your question

Ask a Question

731 491 924 answers to any question