【问题标题】:Updating State Value Across File Functions in React.js在 React.js 中跨文件函数更新状态值
【发布时间】:2021-02-04 21:36:36
【问题描述】:

我希望我的代码跨文件函数(App.js 和 startMenu.js)更新变量“currentPage”。目前我可以只使用 App.js 来处理状态,但想简化我的代码,以便我可以使用目录中的其他 *.js 文件。现在 startMenu.js 以 App.toMainMenu 和 App.toLevelBuilder 的形式从 App.js 调用,但它没有像我希望的那样更新状态变量“currentPage”onClick。

App.js:

import React, {useState} from "react";
import startMenu from "./startMenu";
import levelBuilder from "./levelBuilder";

function App(){
  
  const[currentPage, setPage] = useState("start")

  function toMainMenu(){
    setPage(prevPage => "main")
  }

  function toLevelBuilder(){
    setPage(prevPage => "levels")
  }

  function renderSwitch(param) {
    switch(param) {
      case 'levels':
        return levelBuilder();
      default:
        return startMenu();
    }
  }

  return (
    <div >            
          <span>{currentPage}</span>
          {renderSwitch(currentPage)}            
    </div>
  )
  
}
export default App;

startMenu.js

import React, {useState} from "react";
import levelBuilder from "./levelBuilder";
import App from "./App";

function startMenu() {
    return(
        <div className="container">      
            {/* start menu */}
            <img id = "scan_logo"src={process.env.PUBLIC_URL + '/scanlogo.png'} /> 
            <button id="menuStart" onClick={App.toMainMenu}> START </button>
            <button id="menuLevel" onClick={App.toLevelBuilder}> LEVEL BUILDER </button>        
        </div>
    )
}
export default startMenu;

我在想我需要使用道具,但作为一个 React.js 初学者,这让我有点困惑。任何想法将不胜感激!

谢谢!

【问题讨论】:

  • 你使用函数式组件而不是类组件有什么原因吗?
  • 你可以把你的代码放在codesandbox上方便
  • 功能组件和钩子是要走的路。
  • 我正在使用功能组件,因为我的印象是不能将状态与类组件一起使用
  • 如果您希望跨组件管理您的状态,您将需要使用Redux 库或context

标签: javascript reactjs state jsx react-props


【解决方案1】:

如果我理解正确,您有两个页面,主菜单和关卡生成器,您想切换正在渲染的页面,对吧?最好的方法是使用库 react-router-dom,在你的应用中创建路由,你可以找到更多关于它的信息here

但是,如果您真的想使用普通的 react 状态来执行此操作,您可以将函数 setPage() 作为道具传递给其他两个组件,并从中调用它。这也应该有效。

【讨论】:

  • 不幸的是,如果我没记错的话,react router 修改了 url,我试图让代码在同一个域名下运行。至于将 setPage 作为道具传递,您能否提供一个示例?
  • 您必须将setPage 作为参数传递给功能组件,例如levelBuilder(setPage)mainMenu(setPage)。然后,在组件内部,您必须在 onClick 内部调用它。在这种情况下,您必须将toMainMenu()toLevelBuilder() 放在各个组件中,或者直接从onClick() 调用setPage("levels")
【解决方案2】:

使用功能组件。我在家里把它写在一个文本文件上,所以它可能无法编译,但是如果你想从你的子功能组件调用你的父函数,这是一种方法。

app.js

import React, {useState} from "react";
import StartMenu from "./StartMenu";
import LevelBuilder from "./LevelBuilder";

function App(){
    const [currentPage, setPage] = useState("start")

    function toMainMenu(){
        setPage(prevPage => "main")
    }

    function toLevelBuilder(){
        setPage(prevPage => "levels")
    }

    
    let jsx_element = null;

    switch(currentPage){
        case 'levels':
            jsx_element = <LevelBuilder/>;
            break;
        default:
            jsx_element = <StartMenu toMainMenu={toMainMenu} toLevelBuilder={toLevelBuilder}/>; 
    }

    return (
        <div>            
            <span>{currentPage}</span>
            {jsx_element}            
        </div>
    )

    }
export default App;

StartMenu.js

import React from "react";

function StartMenu(props) {
    return(
        <div className="container">
            <img id = "scan_logo"src={process.env.PUBLIC_URL + '/scanlogo.png'} /> 
            <button id="menuStart" onClick={props.toMainMenu}> START </button>
            <button id="menuLevel" onClick={props.toLevelBuilder}> LEVEL BUILDER </button>        
        </div>
    )
}
export default StartMenu;

【讨论】:

  • 感谢您的帮助,但似乎 startMenu 仍然无法访问 App.js。随着您的更改,我目前收到错误“TypeError:无法读取未定义的属性'toMainMenu'”,我认为这是因为 startMenu.js 不知道在哪里可以找到 toMainMenu()
  • Null 的代码有一些小问题,但不会导致您遇到的错误。您的错误是说 props 在 StartMenu.js 中未定义,但事实并非如此。这是它工作的代码框:codesandbox.io/s/priceless-lehmann-8lgoc?file=/src/App.js
【解决方案3】:

先提几个小指点:

  • 您的组件名称(startMenulevelBuilder)应使用 Pascal 大小写
  • 通常的做法是状态变量和“设置”函数名称匹配,即currentPagesetCurrentPage

对您而言,最好的方法可能是将setCurrentPage&lt;App /&gt; 传递到&lt;StartMenu /&gt;。然后在&lt;StartMenu /&gt;中当用户点击一个按钮时可以调用setCurrentPage('...')

您可以做的另一件事(但对您来说太过分了)是查看useContext

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2017-02-26
    • 2018-02-19
    • 1970-01-01
    • 1970-01-01
    • 2016-06-12
    • 2018-02-23
    • 2021-08-24
    相关资源
    最近更新 更多