Поднятие состояния до основного компонента в приложении React с использованием хуков - PullRequest
1 голос
/ 06 апреля 2019

Я изучаю реагирование и пытаюсь реализовать мелочи для практики. Идея проста: добавить записи (feedbackTasks) в базу данных и перечислить эти записи (при первой загрузке страницы и позже при добавлении новой записи). Пожалуйста, смотрите изображение ниже.

enter image description here

Основным компонентом является ManageFeedbackTasks. Я храню список элементов feedbackTask в его состоянии (st_feedbackTaskList). Обновление этого списка выполняется с помощью функции add_to_st_feedbackTask. Если этот список создается впервые, все извлеченные данные (поступающие из компонента PrintFeedbackTasks) устанавливаются на st_feedbackTaskList. Если нет, то в список вставляется только добавленный элемент (начиная с ShowAddingFeedbackTaskForm).

export function ManageFeedbackTasks() {
    const [st_feedbackTaskList, setFeedbackTaskList] = useState([]);

    const add_to_st_feedbackTask = (data) => {

        if (st_feedbackTaskList.length == 0) {
            setFeedbackTaskList(data);
        } else {
            const { id, title, description } = data;
            setFeedbackTaskList([...st_feedbackTaskList, { id, title, description }]);
        }
    }

    return (
        <>
            <ShowAddingFeedbackTaskForm onAddingItem={add_to_st_feedbackTask} />
            <PrintFeedbackTasks onListingFeedbackTasks={add_to_st_feedbackTask} feedbackTasks={st_feedbackTaskList} />
        </>
    );
}

Ниже приведена функция PrintFeedbackTasks. Эта функция получает список feedbackTasks от основного компонента ManageFeedbackTasks. Этот список впервые выбирается из базы данных с помощью fetchFeedbackTasks. Внутри fetchFeedbackTasks, props.onListingFeedbackTasks(response.data) отправляет извлеченный список обратно в основной компонент для обновления состояния (st_feedbackTaskList).

const PrintFeedbackTasks = (props) => {    
    const [st_isInitialized, setInitialized] = useState(false);    

    const fetchFeedbackTasks = () => {
        axios.get('api/FeedbackTask/Index')
            .then(response => props.onListingFeedbackTasks(response.data))
            .catch(error => console.log(error));
    }    

    useEffect(() => {
        if (!st_isInitialized) {
            fetchFeedbackTasks();
        }
        setInitialized(true);
    });

    return (
        <React.Fragment>
           {
                props.feedbackTasks.map(taskItem =>....
           }
        </React.Fragment>
    );
}

Компонент ниже отображает форму добавления и обрабатывает отправку формы. При добавлении нового элемента этот новый элемент снова отправляется обратно в основной компонент с помощью props.onAddingItem.

const ShowAddingFeedbackTaskForm = (props) => {
    const [st_title, setTitle] = useState('');
    const [st_description, setDescription] = useState('');

    const handleSubmit = async (event) => {
        event.preventDefault();
        await axios(...)
        .then(function (response) {
                setTitle('');
                setDescription('');

            //This will update the list of the feedback task in the main component
                props.onAddingItem({
                   id: response.data,
                   title: st_title,
                   description: st_description
                });

            //GET THE ID HERE
            console.log(response.data);

        }).catch(function (error) {
            console.log(error);
        });
    }


    return (
        <form onSubmit={handleSubmit}>
            <input
                placeholder="Title..."
                type="text"
                value={st_title}
                onChange={(event) => setTitle(event.target.value)}
            />
            <input
                placeholder="Description..."
                type="text"
                value={st_description}
                onChange={(event) => setDescription(event.target.value)}
            />
            <button>Add Feedback Task</button>
        </form>
    );
}

Интересно, а надежен ли этот способ поднятия и управления государством? Есть предложения по улучшению кода? Кроме того, мне интересно, стоит ли мне размещать эти компоненты на их собственных страницах (например, одну страницу или добавление записи, а другую - для листинга). Будет ли это иметь больше смысла в мире react? 1034 *

1 Ответ

1 голос
/ 06 апреля 2019

Идея поднять состояние до родителя верна.Однако из-за структуры вашего кода вы можете вызывать много повторных визуализаций, и в вашем решении можно сделать несколько оптимизаций производительности.Еще одна вещь: вместо того, чтобы извлекать FeedbackTasks в PrintFeedbackTasks компоненте, вы должны сделать это в самом родителе.Кроме того, useEffect принимает второй параметр, который можно использовать для его запуска при первоначальном монтировании

. Вы также можете использовать useCallback ловушку для запоминания функций.

ManageFeedbackTasks

export function ManageFeedbackTasks() {
    const [st_feedbackTaskList, setFeedbackTaskList] = useState([]);

    const fetchFeedbackTasks = useCallback(() => {
        axios.get('api/FeedbackTask/Index')
            .then(response => props.onListingFeedbackTasks(response.data))
            .catch(error => console.log(error));
    }, []);    

    useEffect(() => {
        fetchFeedbackTasks();
    }, []);

    const add_to_st_feedbackTask = useCallback((data) => {

        setFeedbackTaskList(prevTaskList => {
          if (prevTaskList.length == 0) {
            return data;
          } else {
            const { id, title, description } = data;
            return [...prevTaskList, { id, title, description }];
          }
        });
    }, [])

    return (
        <>
            <ShowAddingFeedbackTaskForm onAddingItem={add_to_st_feedbackTask} />
            <PrintFeedbackTasks onListingFeedbackTasks={add_to_st_feedbackTask} feedbackTasks={st_feedbackTaskList} />
        </>
    );
}

PrintFeedbackTasks

const PrintFeedbackTasks = (props) => {    

    return (
        <React.Fragment>
           {
                props.feedbackTasks.map(taskItem =>....
           }
        </React.Fragment>
    );
}

Что касается идеи разделения, показа и обновления TaskList, то это решение о продукте, которое может быть принято в зависимости от длины списка, который пользователь должен заполнить за один раз

...