繁体   English   中英

JavaScript React:将道具从子组件中的 function 传递到父组件中的 function 时出现问题

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

我正在处理将道具从其子组件传递给父组件的问题。

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

父组件(应用程序)

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;

子组件(标题)

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;

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

只要我只从 App 组件中将值传递给 function,代码就可以正常工作。 每当我点击 header 中的一个按钮时,它会在“switchPaneHandler function 中正确显示“paneName” ,然后在“LoadPaneHandler”中打印为“未定义”。

我对 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,但在父组件中,您试图获取 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 />
    }
}

我认为这里的关键问题可能是由于对“什么是道具?什么是 state?”的混淆造成的。 - 在开始使用 React 时非常常见。

如果我们首先查看父组件,您将LoadPaneHandler传递给您的Header ,就像它是一个回调 function。 这不是我们在 React 中的做法。 我们需要提供一个回调 function,它采用我们希望父级显示的窗格的名称。 为了使事情更清晰,命名也确实有帮助 以下是我如何重写你的父母:

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 ,因此您可以了解重新渲染和响应( React -ing)更改的时间。 如果你不熟悉useState() ,如果你要构建有用的 React 应用程序,这是你绝对必须了解的一个 React 钩子——这里是文档

现在为了孩子。 您有一个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>
    );
}

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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM