ReactJS - 从数据库获取数据并从 .then 返回到返回函数返回承诺结果

dmi*_*er1 -2 javascript promise reactjs

太长了;基本上,我试图弄清楚如何在加载时将数据从我的 api 获取到我的 React 应用程序中,以便我的应用程序立即可用。如果需要的话,我完全可以重做或重新编写下面的任何或全部代码。我只需要弄清楚如何做到这一点。我认为它需要进入上下文,以便我的所有组件都可以访问它。

我使用硬编码的虚拟数据创建了一个 ReactJS 应用程序,并且效果很好。现在我们需要将其转换为从数据库中提取真实的动态数据,并且无法理解 Promise 如何与状态和 useEffect 一起工作。它变得如此令人困惑。我在最后一次调用中创建 contextValue 对象,.then并且我需要在return. 我尝试将其保存到状态变量,但这似乎不起作用。TypeError: _useContext is null我在另一个文件中收到错误。

这是整个上下文文件,其中删除了所有不相关的代码:

import PropTypes from 'prop-types';

export const ScheduleContext = createContext();

export const ScheduleProvider2 = (props) => {
    const allChemicals = [...];

    const allBOMs = [...];

    const makeRandomStr = (length) => {...};

    const getRandomChemicals = () => {};

    const getRandomBOMs = () => {..};

    const getRandomIntInclusive = (min, max) => {...};

    const randomDate = (start, end, startHour, endHour) => {...};

    const quotes = [...];

    const getRandomComments = () => {..};

    const getBatchNumbers = () => {...};

    const [context, setContext] = useState(null);
    const [orders, setOrders] = useState(null);
    const [filteredOrders, setFilteredOrders] = useState(null);
    const [pendingOrderIDs, setPendingOrderIDs] = useState(null);
    const [activeOrder, setActiveOrder] = useState(0);
    const [columns, setColumns] = useState([]);
    const [showDetails, setShowDetails] = useState(false);
    const [title, setTitle] = useState('Title');
    const [lineType, setLineType] = useState('Type');
    const chemicals = useState(allChemicals);
    const BOMs = useState(allBOMs);

    useEffect(() => {
        const fetchPendingOrders = () => {
            const ordersURL = 'http://localhost:3001/orders';
            return fetch(ordersURL, {
                cache: 'no-cache', // *default, no-cache, reload, force-cache, only-if-cached
                headers: {
                    'Content-Type': 'application/json'
                },
                referrerPolicy: 'no-referrer' // no-referrer, *client
            });
        };

        fetchPendingOrders()
            .then((result) => {
                return result.json();
            })
            .then((data) => {
                const tempOrders = data.map((el, index) => {
                    return {
                        id: index,
                        .....
                    };
                });

                setOrders(tempOrders);
                setFilteredOrders(tempOrders);
                const pendingOrderIDVals = tempOrders.map(function(val) {
                    return val.id;
                });
                setPendingOrderIDs(pendingOrderIDVals);

                const contextValue = {
                    orders,
                    setOrders,
                    filteredOrders,
                    setFilteredOrders,
                    pendingOrderIDs,
                    setPendingOrderIDs,
                    columns,
                    setColumns,
                    showDetails,
                    setShowDetails,
                    activeOrder,
                    setActiveOrder,
                    title,
                    setTitle,
                    lineType,
                    setLineType,
                    chemicals,
                    BOMs
                };
                setContext(contextValue);

                console.log(contextValue);
            })
            .catch((e) => {
                console.log(e);
            });
    }, []);



    return (
        <ScheduleContext.Provider value={context}>
            {props.children}
        </ScheduleContext.Provider>
    );
};
Run Code Online (Sandbox Code Playgroud)

该错误TypeError: _useContext is null发生在读取上下文文件的文件中的功能组件中。这是两行相关的行(这是发生错误的 SchedulePage.js 的开头):

import { ScheduleContext } from '../../schedule-context-new';

const Schedule = () => {
const {
        showDetails,
        orders,
        setOrders,
        activeOrder,
        columns,
        setColumns,
        title,
        pendingOrderIDs,
        filteredOrders,
        setTitle,
        lineType,
        setLineType
    } = useContext(ScheduleContext);
....
Run Code Online (Sandbox Code Playgroud)

如果有影响的话,我还在我的 app.js 中使用 ScheduleProvider :

import { ScheduleProvider2 } from './schedule-context-new';
import Schedule from './components/home/SchedulePage';
import './App.scss';

const App = () => {
    return (
        <ScheduleProvider2>
            <div className={'App'}>
                <Schedule />
            </div>
        </ScheduleProvider2>
    );
};
Run Code Online (Sandbox Code Playgroud)

更新: 根据示例链接,我尝试将上下文文件的末尾更改为此,现在它抱怨Error: ScheduleProvider2(...): Nothing was returned from render.

(async function() {
        const context = await fetchPendingOrders();

        return (
            <ScheduleContext.Provider value={context}>
                {props.children}
            </ScheduleContext.Provider>
        );
    })();
};
Run Code Online (Sandbox Code Playgroud)

更新 2 - 我已经弄清楚如何创建我的应用程序的基本准系统副本,该副本实际上会产生相同的错误。再次由于某种原因,在我注释掉 useEffect 之前,useEffect 代码没有被调用,我不知道为什么。 https://codesandbox.io/s/tender-cookies-jzn5v

Ale*_*lex 5

您应该等待 API 结果

const Schedule = () => {
  const {
    orders,
    setOrders,
    filteredOrders,
    setFilteredOrders,
    pendingOrderIDs,
    setPendingOrderIDs
  } = useContext(ScheduleContext) ||[];
Run Code Online (Sandbox Code Playgroud)

或者使用useEffect

const data = useContext(ScheduleContext);

useEffect(() => {
  // Do you calculation here when ScheduleContext is ready
}, [data])
Run Code Online (Sandbox Code Playgroud)

代码沙盒