【问题标题】:Trying to call useContext outside of a function component试图在函数组件之外调用 useContext
【发布时间】:2020-03-10 23:36:19
【问题描述】:

我正在尝试弄清楚如何正确使用 React 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;

【问题讨论】:

    标签: reactjs state


    【解决方案1】:

    不是听起来油嘴滑舌,但本质上它的意思正是它所说的。 onDragEnd 不是 React 组件,因为它没有返回 ReactElement 或某种 JSX。如果您编辑了空白返回语句以返回 &lt;div&gt;(对于所有路径),它将被视为一个组件并且可以正常工作,但目前它没有返回任何内容。

    【讨论】:

    • 但是这两个条件,我想取消而不做任何事情。必须有更好的方法来做我想做的事情。
    • 你可以在组件中定义函数,它可以访问上下文。
    • 所以把 onDragEnd 放在 Schedule 里面?
    • 我不完全确定您的项目的结构或是否有任何副作用,但它肯定可以工作。
    【解决方案2】:

    使用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 或拉出更多内容并制作自定义挂钩。

    【讨论】:

    • 由于某种原因,它没有将 onCallback 识别为函数
    • 你必须从 React 导入它。
    • 我才意识到你写了onCallback。 API 是useCallback
    猜你喜欢
    • 1970-01-01
    • 2020-10-27
    • 1970-01-01
    • 2021-03-06
    • 2020-11-18
    • 2018-09-23
    • 1970-01-01
    • 2021-08-19
    • 2020-07-30
    相关资源
    最近更新 更多