尝试在功能组件之外调用useContext

时间:2019-11-14 21:03:14

标签: reactjs state

我试图弄清楚如何正确使用React Context。我很想尝试从功能组件外部访问Context的问题。我遇到了错误:

  

9:18行:在函数“ onDragEnd”中调用React Hook“ useContext”,该函数既不是React函数组件也不是自定义的React Hook函数react-hooks / rules-of-hooks

这是我的整个Schedule js文件:

import React, { useContext } from 'react';
import PropTypes from 'prop-types';
import { DragDropContext } from 'react-beautiful-dnd';
import OrderColumn from '../ordercolumn/OrderColumn';
import { ScheduleContext } from '../../schedule-context';

const onDragEnd = (result) => {
    const { destination, source, draggableId } = result;
    const context = useContext(ScheduleContext); // <-- issue is here

    if (!destination) {
        return;
    }

    if (
        destination.droppableId === source.droppableId &&
        destination.index === source.index
    ) {
        return;
    }

    const column = context.columns[source.droppableId];
    const orderIDs = Array.from(column.orderIDs);
    orderIDs.splice(source.index, 1);
    orderIDs.splice(destination.index, 0, draggableId);

    const newColumn = {
        ...column,
        orderIDs: orderIDs
    };

    const newColumns = {
        ...context.columns,
        newColumn
    };

    context.setColumns(newColumns);
};

const Schedule = () => {
    const { orders, setOrders, columns, setColumns } = useContext(
        ScheduleContext
    );
    return (
        <DragDropContext onDragEnd={onDragEnd}>
            <div className={'full-width'}>
                <h1 className={'text-center'}>Schedule</h1>
                <div className={'lines row no-gutters'}>
                    {columns.map(function(val, index) {
                        if (index === 0) {
                            return (
                                <OrderColumn
                                    title={val.title}
                                    columnId={index}
                                    orders={orders}
                                    setOrders={setOrders}
                                    setColumns={setColumns}
                                />
                            );
                        } else {
                            return (
                                <OrderColumn
                                    title={val.title}
                                    columnId={index}
                                    setOrders={setOrders}
                                    setColumns={setColumns}
                                />
                            );
                        }
                    })}
                </div>
            </div>
        </DragDropContext>
    );
};

Schedule.propTypes = {
    orders: PropTypes.array
};

export default Schedule;

2 个答案:

答案 0 :(得分:2)

听起来不像是glib,但从本质上讲,它的意思恰恰是它所说的。 onDragEnd不是React组件,因为它没有返回ReactElement或某种JSX。如果您编辑了空白的return语句以返回<div>(对于所有路径),它将被认为是一个组件并且可以正常工作,但是到目前为止,它不返回任何内容。

答案 1 :(得分:0)

使用useCallback并将上下文传递给该函数将有助于解决您的问题。

以下示例:

const onDragEnd(result, context) => {
    // Adjust as necessary
}

const Schedule = () => {
    const context = useContext(ScheduleContext);
    const onDragEnd = useCallback((result) => onDragEnd(result, context), [context]);
    return <DragDropContext onDragEnd={onDragEnd}>

您还可以内联onDragEnd或拉出更多并制作自定义挂钩。