簡體   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