Reactjs 状态变量未从上下文更改

Reactjs 状态变量未从上下文更改,reactjs,state,Reactjs,State,我一定是设置了错误的上下文或状态。但由于某些原因,我无法更改我的showDetails状态。当有条件地添加引导类d-none时,它应该显示一个隐藏列。我的订单组件上有一个单击事件,它运行setShowDetails(true),但不起作用。该函数中的其他内容确实在运行 我的订单组件中的相关代码: const Order = props => { const { orderID } = props; const { setShowDetails } = useScheduleActi

我一定是设置了错误的上下文或状态。但由于某些原因,我无法更改我的
showDetails
状态。当有条件地添加引导类
d-none
时,它应该显示一个隐藏列。我的订单组件上有一个单击事件,它运行
setShowDetails(true)
,但不起作用。该函数中的其他内容确实在运行

我的订单组件中的相关代码:

const Order = props => {
  const { orderID } = props;
  const { setShowDetails } = useScheduleActionsContext();

  // show the details section when user clicks an order
  const showDetails = orderID => {
    console.log("showDetails function!");
    // needed to fix an issue with doubled borders between the columns
    document.querySelector(".lines .col.last").style.borderRightWidth = "0px";
    setShowDetails(true);
  };

  return (
    <MyOrder className={"order"} onClick={e => showDetails(orderID, e)}>
      <div className={"orderID"}>{orderID}</div>
      <h3>Order</h3>
    </MyOrder>
  );
};
这是我的整个上下文文件:

import React, {
  createContext,
  useContext,
  useEffect,
  useState,
  useMemo
} from "react";
import { useGlobalSpinnerActionsContext } from "./GlobalSpinnerContext";
import PropTypes from "prop-types";

// export const ScheduleContext = createContext({
//   title: "My title"
// });

const pageTitle = "My Title";

const initialValues = {
  title: pageTitle,
  filteredOrders: [],
  columns: []
};

const ScheduleContext = createContext(initialValues);
const ScheduleActionsContext = createContext({});

export const useScheduleContext = () => useContext(ScheduleContext);
export const useScheduleActionsContext = () =>
  useContext(ScheduleActionsContext);

export const ScheduleProvider2 = props => {
  const setGlobalSpinner = useGlobalSpinnerActionsContext();
  setGlobalSpinner(true);
  console.log(setGlobalSpinner);

  const [context, setContext] = useState({});
  // eslint-disable-next-line no-unused-vars
  const [orders, setOrders] = useState([]);
  // eslint-disable-next-line no-unused-vars
  const [filteredOrders, setFilteredOrders] = useState([]);
  // eslint-disable-next-line no-unused-vars
  const [pendingOrderIDs, setPendingOrderIDs] = useState([]);
  const [lineType, setLineType] = useState(pageTitle);
  const [title, setTitle] = useState(pageTitle);
  const [columns, setColumns] = useState([]);
  const [showDetails, setShowDetails] = useState(false);

  useEffect(() => {
    setGlobalSpinner(true);
    console.log("we are running useEffect in context!!!");
    const fetchPendingOrders = async () => {
      const ordersURL = "https://randomuser.me/api";
      return await 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.results.map((el, index) => {
          return {
            id: index,
            gender: el.gender
          };
        });
        console.log("tempOrders: ", tempOrders);
        setOrders(tempOrders);
        setFilteredOrders(tempOrders);
        const pendingOrderIDVals = tempOrders.map(function(val) {
          return val.id;
        });
        setPendingOrderIDs(pendingOrderIDVals);

        const contextValue = {
          orders: tempOrders,
          setOrders,
          showDetails,
          title,
          columns
        };
        setContext(contextValue);
        setGlobalSpinner(false);
        console.log(contextValue);
      })
      .catch(e => {
        console.log(e);
      });
  }, [setGlobalSpinner]);

  const actionsValues = useMemo(() => {
    return {
      setLineType,
      setColumns,
      setTitle,
      setShowDetails,
      setFilteredOrders,
      setPendingOrderIDs
    };
  }, []);

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

ScheduleProvider2.propTypes = {
  children: PropTypes.oneOfType([
    PropTypes.arrayOf(PropTypes.node),
    PropTypes.node
  ]).isRequired
};
import-React{
createContext,
使用上下文,
使用效果,
useState,
使用备忘录
}从“反应”;
从“/GlobalSpinnerContext”导入{useGlobalSpinnerActionsContext};
从“道具类型”导入道具类型;
//导出常量ScheduleContext=createContext({
//标题:“我的标题”
// });
const pageTitle=“我的标题”;
常量初始值={
标题:pageTitle,
过滤器制造商:[],
列:[]
};
const ScheduleContext=createContext(初始值);
const ScheduleActionsContext=createContext({});
export const useScheduleContext=()=>useContext(ScheduleContext);
导出常量useScheduleActionsContext=()=>
useContext(ScheduleActionsContext);
导出常量ScheduleProvider2=props=>{
常量setGlobalSpinner=useGlobalSpinnerActionsContext();
setGlobalSpinner(真);
console.log(setGlobalSpinner);
const[context,setContext]=useState({});
//eslint禁用下一行无未使用的变量
const[orders,setOrders]=useState([]);
//eslint禁用下一行无未使用的变量
常量[filteredOrders,setFilteredOrders]=useState([]);
//eslint禁用下一行无未使用的变量
const[pendingOrderIDs,setPendingOrderIDs]=useState([]);
常量[lineType,setLineType]=使用状态(pageTitle);
const[title,setTitle]=使用状态(pageTitle);
const[columns,setColumns]=useState([]);
const[showDetails,setShowDetails]=useState(false);
useffect(()=>{
setGlobalSpinner(真);
log(“我们正在上下文中运行useffect!!!”;
常量fetchPendingOrders=async()=>{
常量ordersURL=”https://randomuser.me/api";
返回等待获取(ordersURL{
缓存:“无缓存”,//*默认值,无缓存,重新加载,强制缓存,仅在缓存时
标题:{
“内容类型”:“应用程序/json”
},
推荐人政策:“无推荐人”//无推荐人,*客户
});
};
fetchPendingOrders()
。然后(结果=>{
返回result.json();
})
。然后(数据=>{
const tempOrders=data.results.map((el,索引)=>{
返回{
id:索引,
性别:el.gender
};
});
console.log(“tempOrders:”,tempOrders);
设置命令(临时命令);
设置过滤器过滤器(临时过滤器);
const pendingOrderIDVals=tempOrders.map(函数(val)){
返回val.id;
});
设置PendingOrderIDs(pendingOrderIDVals);
常量上下文值={
命令:临时命令,
设定命令,
展示细节,
标题
柱
};
setContext(contextValue);
setGlobalSpinner(假);
console.log(contextValue);
})
.catch(e=>{
控制台日志(e);
});
},[setGlobalSpinner]);
const actionsValues=useMemo(()=>{
返回{
setLineType,
设置列,
片名,
设置显示详细信息,
SetFilteredorers,
设置挂起装置
};
}, []);
返回(
{props.children}
);
};
ScheduleProvider2.propTypes={
儿童:PropTypes.oneOfType([
PropTypes.arrayOf(PropTypes.node),
PropTypes.node
]).需要
};
我还创建了一个代码沙盒,这样就可以对其进行测试和播放,并对代码进行调整。如果单击其中一个蓝色订单框,则应显示“订单详细信息”列。

好吧,我找到了它不起作用的原因

  • 必须将
    showDetails:false
    添加到
    ScheduleContext
    组件
  • 必须将
    showDetails
    作为依赖项添加到
    useffect
    hook-like:

  • 天哪,就是这样!!非常感谢你!!我们能够找出如何使它更高效,所以它不会每次都使用这个答案中的知识运行useffect。再次感谢!
    import React, {
      createContext,
      useContext,
      useEffect,
      useState,
      useMemo
    } from "react";
    import { useGlobalSpinnerActionsContext } from "./GlobalSpinnerContext";
    import PropTypes from "prop-types";
    
    // export const ScheduleContext = createContext({
    //   title: "My title"
    // });
    
    const pageTitle = "My Title";
    
    const initialValues = {
      title: pageTitle,
      filteredOrders: [],
      columns: []
    };
    
    const ScheduleContext = createContext(initialValues);
    const ScheduleActionsContext = createContext({});
    
    export const useScheduleContext = () => useContext(ScheduleContext);
    export const useScheduleActionsContext = () =>
      useContext(ScheduleActionsContext);
    
    export const ScheduleProvider2 = props => {
      const setGlobalSpinner = useGlobalSpinnerActionsContext();
      setGlobalSpinner(true);
      console.log(setGlobalSpinner);
    
      const [context, setContext] = useState({});
      // eslint-disable-next-line no-unused-vars
      const [orders, setOrders] = useState([]);
      // eslint-disable-next-line no-unused-vars
      const [filteredOrders, setFilteredOrders] = useState([]);
      // eslint-disable-next-line no-unused-vars
      const [pendingOrderIDs, setPendingOrderIDs] = useState([]);
      const [lineType, setLineType] = useState(pageTitle);
      const [title, setTitle] = useState(pageTitle);
      const [columns, setColumns] = useState([]);
      const [showDetails, setShowDetails] = useState(false);
    
      useEffect(() => {
        setGlobalSpinner(true);
        console.log("we are running useEffect in context!!!");
        const fetchPendingOrders = async () => {
          const ordersURL = "https://randomuser.me/api";
          return await 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.results.map((el, index) => {
              return {
                id: index,
                gender: el.gender
              };
            });
            console.log("tempOrders: ", tempOrders);
            setOrders(tempOrders);
            setFilteredOrders(tempOrders);
            const pendingOrderIDVals = tempOrders.map(function(val) {
              return val.id;
            });
            setPendingOrderIDs(pendingOrderIDVals);
    
            const contextValue = {
              orders: tempOrders,
              setOrders,
              showDetails,
              title,
              columns
            };
            setContext(contextValue);
            setGlobalSpinner(false);
            console.log(contextValue);
          })
          .catch(e => {
            console.log(e);
          });
      }, [setGlobalSpinner]);
    
      const actionsValues = useMemo(() => {
        return {
          setLineType,
          setColumns,
          setTitle,
          setShowDetails,
          setFilteredOrders,
          setPendingOrderIDs
        };
      }, []);
    
      return (
        <ScheduleContext.Provider value={context}>
          <ScheduleActionsContext.Provider value={actionsValues}>
            {props.children}
          </ScheduleActionsContext.Provider>
        </ScheduleContext.Provider>
      );
    };
    
    ScheduleProvider2.propTypes = {
      children: PropTypes.oneOfType([
        PropTypes.arrayOf(PropTypes.node),
        PropTypes.node
      ]).isRequired
    };
    
    useEffect(() => {
       ...
     }, [setGlobalSpinner, showDetails]);