【问题标题】:ReactJS - getting data from DB and returning promise results from .then back to return functionReactJS - 从数据库获取数据并从 .then 返回承诺结果返回函数
【发布时间】:2020-02-08 01:03:37
【问题描述】:

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

我创建了一个带有硬编码虚拟数据的 ReactJS 应用程序,它运行良好。现在我们需要将其转换为从数据库中提取真实的动态数据,并且在理解 Promise 如何与 state 和 useEffect 一起工作时遇到了麻烦。它变得如此混乱。我在最后的.then 调用中创建了 contextValue 对象,我需要在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>
    );
};

错误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);
....

如果有区别的话,我也在我的 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>
    );
};

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

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

        return (
            <ScheduleContext.Provider value={context}>
                {props.children}
            </ScheduleContext.Provider>
        );
    })();
};

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

【问题讨论】:

  • 那么我会在底部的 return 周围包裹一个 IIFE 函数吗?
  • @jonrsharpe 不?
  • useContext 只能在功能性反应组件内部使用。
  • 编辑显示我在功能性反应组件中使用 useContect。
  • @dmikester1,您能否在代码和框环境中提供一个最小的、可重现的样本?

标签: javascript reactjs promise


【解决方案1】:

您应该等待 API 结果

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

或使用useEffect

const data = useContext(ScheduleContext);

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

codesandbox

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2016-03-09
    • 1970-01-01
    • 2017-04-05
    • 1970-01-01
    • 2020-03-06
    • 2018-05-16
    • 1970-01-01
    相关资源
    最近更新 更多