【问题标题】:How to access state in function which is in another file如何访问另一个文件中的函数状态
【发布时间】:2020-08-02 15:42:56
【问题描述】:

今天我完成了我的第一个 React 应用 - 计算器。

我虽然最好让 App.js 干净并将所有逻辑功能放在单独的文件 Logic.js 中,以及所有设计功能(根据数字或点击动画按钮的长度更改输出字体大小) 例如 Effects.js。

当我获取函数时出现问题,将它们放在新文件中(当然导出它们并在 app.js 中导入它们)。

错误说 setNumber(当我想使用状态时调用的方法),

number.firstNumber(firstNumber 状态,保存第一个点击的数字),

并且我在这个文件中调用的每个状态(函数或条件)都没有定义,所以这意味着这个文件无法访问 App.js 状态。有什么办法可以让这些功能分开,而不必重新构建整个应用程序,这样我就可以实现干净的代码?

App.js 创建我在这些函数中使用的状态

const [number, setNumber] = useState({
firstNumber: "",
secondNumber: "",
operator: "",
result: "0",
displayed: "0",
cButton: "AC",
cButtonCheck: false,
numToReset: false,
sizeOfOutput: "1em",
isOrange: false
});

未定义 setNumber 错误的新文件中的函数示例

function turnOnOrange(operator) {
if (number.isOrange === false)     {
  setNumber(prevState => ({
    ...prevState,
    isOrange: true,
    whichOrange: operator
  }));
  operator.className = "orangeActivated";
}
}

谢谢,链接让你可以看到整个代码

https://codesandbox.io/embed/youthful-platform-n6lvs?fontsize=14&hidenavigation=1&theme=dark&codemirror=1

【问题讨论】:

    标签: javascript reactjs function state


    【解决方案1】:

    我认为你可以定义自己的钩子来管理部分状态,因为 Hook 是为了共享状态而生的。这是一个例子:

    yourHook.js

    
    export function colorHook(initValue) {
      const [color, setColor] = React.useState(initValue);
    
      // Define whatever you want
      const setOrange = () => setColor({ isYellow: true }) 
    
      return [color, setColor, setOrange, // pass more ];
    }
    
    

    在您的主文件中:

    
    import { colorHook } from "./yourHook";
    
    function yourComponent() {
      const [color, setColor, setOrange] = colorHook({ /* your value */ }) 
    }
    
    

    【讨论】:

      【解决方案2】:

      您可以将App.js 中的单个状态对象拆分为多个可管理的内聚状态,然后制作您自己的自定义挂钩,该挂钩将操纵您刚刚拆分的部分状态。

      例如对于turnOnOrange 函数,您可以在其自己的文件中创建名为useOrangeHook 的新钩子并将其导入并用作钩子:

      import React, { useState } from "react";
      
      export default function useOrangeHook(operator) {
        const [orangeState, setOrangeState] = useState({
          isOrange: false,
          whichOrange: ""
        });
        if (!orangeState.isOrange) {
          setOrangeState(prevState => ({
            ...prevState,
            isOrange: true,
            whichOrange: operator
          }));
          operator.className = "orangeActivated";
        }
        return orangeState;
      }
      

      自定义 Hook 是一种重用有状态逻辑的机制。查看 React 指南 here

      【讨论】:

      • 这个问题的好答案,这是做你正在寻找的事情的好方法@Pinnci
      • 感谢您的回答。所以,如果我做对了,我必须从 app.js 中删除所有状态,创建它们并在另一个我将导出的文件中使用它们? (对于此示例 isOrange 和 whichOrange)将从 App.js 中删除并在新文件中创建,就像您在回答中向我展示的那样? @Fullstack Guy
      • @Pinnci 是的,您需要将 App.js 中的单个状态对象拆分为逻辑内聚状态,以便由您的自定义挂钩管理。
      • 但是有一个问题。几乎每个函数都链接到另一个函数。我的意思是,例如 turnOnOrange(operator) 在 operator(e) 函数中被调用,当 + - / * 被点击时被调用。所以我不明白这个概念,我应该如何分离这些状态,所以我仍然可以在函数内部调用函数等等。例如,将值“operator”从操作符函数传递到 turnOnOrange 是我点击的那个特定按钮.抱歉,我是 React 新手,还不太了解像这样更复杂的东西。
      【解决方案3】:

      您应该从函数中返回这些变量并导出函数,反之亦然。

      您正在尝试做的事情称为自定义挂钩,我会给您一个示例,您可以在其中进行反思:

      useMyFirstCustomHook.js file
      import React, { useState } from 'react';
      
      const useMyFirstCustomHook = () => {
        const [count, setCount] = useState(0);
        // do some stuff
        return { count, setCount };
      };
      
      export default useMyFirstCustomHook;
      
      App.js file
      //..
      import useMyFirstCustomHook from 'path/to/useMyFirstCustomHook';
      //..
      const { count, setCount } = useMyFirstCustomHook();
      console.log(count);
      

      【讨论】:

        【解决方案4】:

        首先,分离事物很有意义,除非您尝试管理组件的状态。这里的原因是状态完全由包含镜头变量的组件管理,在您的情况下为[number, setNumber]。拥有一个从组件外部调用这些函数的函数会引发一个很大的危险信号,并且您已经注意到它不起作用。

        它不起作用的原因是范围问题。函数turnOnOrange 不会在组件本身的范围内被调用。当您使用函数组件时,this 没有什么意义,所以即使是 turnOnOrange.call(this, operator) 也无济于事。

        所以,虽然我赞赏你想要分离出你的逻辑,但在这种情况下,它对你不利,而且如果你仔细想想,它实际上并不是很直观。您的函数turnOnOrange 绝对属于该组件。

        【讨论】:

        • 感谢您的回答。我虽然和你一样,因为我想从主文件中分离出来的每个函数都在使用条件下的状态,所以你很难过,这些函数就属于那里。我只是想知道如何使最终版本变得漂亮、干净和可读,结果出现了这个问题。
        • 好吧,这里的另一个答案为您提供了一个非常好的解决方案,您可以使用自定义钩子,查看@FullstackGuy 的stackoverflow.com/a/63218230/1010632
        猜你喜欢
        • 2018-02-01
        • 1970-01-01
        • 2019-12-20
        • 2021-08-07
        • 2015-07-16
        • 1970-01-01
        • 2021-02-05
        • 1970-01-01
        • 2020-10-26
        相关资源
        最近更新 更多