JavaScript React:将 prop 从 child 组件中的函数传递到 parent 中的函数时出现问题

JavaScript React: Issues with passing prop from a function in a child component to a function in the parent

我正在处理从 child.

向 parent 组件传递道具的问题

我尝试实现的代码的想法是 header 组件中的一组按钮,单击这些按钮时,会为网站的其他部分加载新的组件页面。我正在处理一些我可以在其他时间修复的小错误,但主要问题是当我尝试传递处理开关的函数的结果时,一旦它们到达 'undefined' 显示的值应用程序组件。我怀疑我解释得很好所以请允许我展示代码。

Parent 组件(应用程序)

import React from "react";
import Header from "./Components/Header/Header";
import Footer from "./Components/Footer/Footer";
import Pane from "./Components/Pane/Pane";
import MainPane from "./Components/Pane/MainPane";
import BookViewPane from "./Components/Pane/BookViewPane";
import AddBookPane from "./Components/Pane/AddBookPane";
import SignInPane from  "./Components/Pane/SignInPane";
import "./App.css";

const App = ()=>{

    function LoadPaneHandler(props){
        var NewPaneName=props.paneName;

        // const NewPaneName={
        //  name: props.paneName
        // };
        
        // const NewPaneName=String(props);

        console.log(NewPaneName);
        switch(NewPaneName){
            case 'MainPane':
                return <MainPane />
            case 'AddBookPane':
                return <AddBookPane />
            case 'BookViewPane':
                return <BookViewPane />
            case 'SignInPane':
                return <SignInPane />
            default:
                return <Pane />
        }
    }

    return(
        <React.Fragment>
            <Header switchPane={LoadPaneHandler} />
            <main>
                <LoadPaneHandler paneName="MainPane" />
            </main>
            <Footer />
        </React.Fragment>
    );
}

export default App;

Child 组件 (Header)

import React from "react";
import "./Header.css";

const Header=(props)=>{
    var paneName="";

    const switchPaneHandler=event=>{
        event.preventDefault();
        console.log(paneName);
        props.switchPane(paneName);
    }

    return(
        <header id="header">
            <div id="header-title">
                <h1>Library</h1>
            </div>
            <div id="header-buttons">
                <button onClick={paneName="BookViewPane",switchPaneHandler}> View Books</button>
                <button onClick={paneName="AddBookPane",switchPaneHandler}> Add Books </button>
                <button onClick={paneName="SignInPane",switchPaneHandler}> Login</button>
            </div>
        </header>
    );
}

export default Header;

我已经包含了我用来获取函数正常工作所需数据的其他方法的注释掉的代码,以便您可以了解我已经尝试过的方法。

只要我只从 App 组件内将值传递给函数,代码就可以正常工作。但是,每当我单击 header 中的一个按钮时,它都会在 'switchPaneHandler' 函数然后在 'LoadPaneHandler' 它打印为 'undefined'.

我对 React 还是很陌生,所以这可能是我犯的一个非常明显的错误,但仍然感谢您的帮助。谢谢!

尝试像这样更改您的子组件(页眉)。

import React from "react";
import "./Header.css";
const Header = (props) => {

    const switchPaneHandler = paneName => {
        console.log(paneName);
        props.switchPane(paneName);
    }

    return(
        <header id="header">
            <div id="header-title">
                <h1>Library</h1>
            </div>
            <div id="header-buttons">
                <button onClick={()=> switchPaneHandler('BookViewPane')}> View Books</button>
                <button onClick={() => switchPaneHandler("AddBookPane")}> Add Books </button>
                <button onClick={() => switchPaneHandler("SignInPane")}> Login</button>
            </div>
        </header>
    );
}

在 header 组件中,您直接传递 paneName,但在 parent 组件中,您试图获得 javascript object (props.paneName),这就是你出错的原因。

const switchPaneHandler=event=>{
    event.preventDefault();
    console.log(paneName);
    props.switchPane(paneName);
}

所以尝试直接访问,

function LoadPaneHandler(paneName){
    var NewPaneName = paneName;

    console.log(NewPaneName);
    switch(NewPaneName){
        case 'MainPane':
            return <MainPane />
        case 'AddBookPane':
            return <AddBookPane />
        case 'BookViewPane':
            return <BookViewPane />
        case 'SignInPane':
            return <SignInPane />
        default:
            return <Pane />
    }
}

我认为这里的关键问题可能是对“什么是道具?什么是状态?”的困惑引起的。 - 在开始使用 React 时很常见。

如果我们首先查看 parent 组件,您会将 LoadPaneHandler 传递给 Header,就像它是一个回调函数一样。这不是我们在 React 中的做法。我们需要提供一个回调函数,该函数采用我们希望 parent 显示的窗格的名称。命名也可以真正帮助 使事情更清楚。这是我重写你的 parent:

的方式
const App = ()=>{
    const [currentPaneName, setCurrentPaneName] = React.useState("MainPane")
    
    function updateCurrentPane(newPaneName) {
      console.log(`Updating pane from ${currentPaneName} to ${newPaneName}`);
      setCurrentPaneName(newPaneName)
    }

    function LoadPaneHandler(){

        console.log(`Showing pane ${currentPaneName}`);
        switch(currentPaneName){
            case 'MainPane':
                return <MainPane />
            case 'AddBookPane':
                return <AddBookPane />
            case 'BookViewPane':
                return <BookViewPane />
            case 'SignInPane':
                return <SignInPane />
            default:
                return <Pane />
        }
    }

    return(
        <React.Fragment>
            <Header onNewPaneSelected={updateCurrentPane} />
            <main>
                <LoadPaneHandler />
            </main>
            <Footer />
        </React.Fragment>
    );
}

我在那里留下了一些 console.log,这样你就可以了解 re-rendering 的时间和响应(React- ing) 改变。如果您不熟悉 useState(),如果您要构建有用的 React 应用程序,这是您绝对 必须 了解的一个 React 钩子 - here are the docs

现在 child。您有一个 paneName 变量,但您不需要它。您真正要做的就是在调用回调时设置正确的参数:

const Header=(props)=>{

    const switchPaneHandler= (paneName) =>{
        event.preventDefault();
        console.log(paneName);
        props. onNewPaneSelected(paneName);
    }

    return(
        <header id="header">
            <div id="header-title">
                <h1>Library</h1>
            </div>
            <div id="header-buttons">
                <button onClick={() => switchPaneHandler("BookViewPane")}> View Books</button>
                <button onClick={() => switchPaneHandler("AddBookPane")}> Add Books </button>
                <button onClick={() => switchPaneHandler("SignInPane")}> Login</button>
            </div>
        </header>
    );
}

注意我更改了它期望作为道具给出的回调函数的名称 - switchPane 有点误导 - 这不是 this 组件的工作来切换窗格,它只需要能够告诉某人用户想要切换。这也使得将来更容易进行更改,例如,如果您有其他对用户希望看到的窗格感兴趣的东西。