【问题标题】:How to connect Parent Component with child Component in React如何在 React 中连接父组件和子组件
【发布时间】:2023-02-25 15:25:14
【问题描述】:

我正在尝试根据城市名称过滤此处的卡片。我认为问题是我无法访问父组件中子组件的状态,而且我似乎无法解决该问题

import { React, useState, useEffect } from "react";
import {Container, Row, Col} from 'react-bootstrap';
import DestCard from "./Card";
import { StyledLink } from "./Home.styled";
import { getCities } from "./api";
import Navbar from "./NavBar"
import ImageCarousel from "./ImageCarousel"
import Grid from '@mui/material/Unstable_Grid2';
import FilterComponent from "./FilterComponent";
import Grid2 from "@mui/material/Unstable_Grid2/Grid2";
import { Button } from "react-bootstrap";

function Home() {
    const [cities, setCities] = useState(getCities());
    
    const [filteringcities, setFilteringCities]= useState(getCities());
    
    // useEffect(()=>{
    //  setCities(cities);
    // },[]);

    // function filterCities()
    // {
    //  let sortedStudents = cities.sort((a, b) => {
    //      if (a.title < b.title) {
    //          return -1;
    //      }
    //      if (a.title > b.title) {
    //          return 1;
    //      }
    //      return 0;
    //  });
    //  setCities(
    //      sortedStudents
    //  )
    // }

    function linkto(){
            let sortedStudents = cities.sort((a, b) => {
                if (a.title < b.title) {
                    return -1;
                }
                if (a.title > b.title) {
                    return 1;
                }
                return 0;
            });
            setCities(
                sortedStudents
            )
    }

    return (
        <div>
            <Navbar />

            <ImageCarousel style={{ width: "100%", height: "500px" }} />

            <FilterComponent onClick={linkto}></FilterComponent>

            {/* <Button variant="outline-dark" onClick={filterCities}>City Name</Button> */}

            <Grid2 container spacing={{ xs: 2 }} columns={{ xs: 4, md: 16 }} style={{marginLeft:"20px", marginTop:"30px"}}>
                {cities.map((details, index) => (
                    <Grid2 item xs={2} sm={4} md={4} key={index}>
                        <StyledLink to={`/city/${details.title}`}>
                            <DestCard details= {details} />
                        </StyledLink>
                    </Grid2>
                ))}
            </Grid2>
        </div>
    )
}

export default Home; 

这是我的父组件或主组件,我有一个子组件 FilterComponent,它是一个'关闭画布'反应引导组件。

import React, {useEffect, useState} from "react";
import Button from 'react-bootstrap/Button';
import Offcanvas from 'react-bootstrap/Offcanvas';
import { StyledButton } from "./FilterComponent.styled";
import Grid2 from "@mui/material/Unstable_Grid2/Grid2";
import { getCities } from "./api";
import { StyledLink } from "./Home.styled";
import DestCard from "./Card.jsx";

const options = [
    {
        name: 'Filters',
        scroll: true,
        backdrop: true,
    },
];

function OffCanvasExample({ name, linkto, ...props}) {
    const [show, setShow] = useState(false);

    const handleClose = () => setShow(false);
    const toggleShow = () => setShow((s) => !s);

    // const [filteringcities, setFilteringCities]= useState(getCities());
    
    // useEffect(()=>{
    //  setFilteringCities(filterCities);
    // },[]);

    // function filterCities()
    // {
    //  let sortedStudents = filteringcities.sort((a, b) => {
    //      if (a.title < b.title) {
    //          return -1;
    //      }
    //      if (a.title > b.title) {
    //          return 1;
    //      }
    //      return 0;
    //  });
    //     console.log(sortedStudents);
    //  setFilteringCities(
    //     //     <Grid2 container spacing={{ xs: 2 }} columns={{ xs: 4, md: 16 }} style={{marginLeft:"20px", marginTop:"30px"}}>
    //     //         {sortedStudents.map((details, index) => (
    //     //             <Grid2 item xs={2} sm={4} md={4} key={index}>
    //     //                 <StyledLink to={`/city/${details.title}`}>
    //     //                     <DestCard details= {details} />
    //     //                 </StyledLink>
    //     //             </Grid2>
    //     //         ))}
    //     // </Grid2>
    //         sortedStudents
    //  )
    // }
    return (
        <>
            <StyledButton variant="primary" onClick={toggleShow} className="me-2">
                {name}
            </StyledButton>
            <Offcanvas show={show} onHide={handleClose} {...props}>
                <Offcanvas.Header closeButton>
                    <Offcanvas.Title>Filters</Offcanvas.Title>
                </Offcanvas.Header>
                <hr></hr>
                <Offcanvas.Body>
                    <Grid2 container spacing={2} columns={{ xs: 4, md: 16}}>
                        <Grid2 xs={2} sm={4} md={4}>
                            <Button variant="outline-dark" onClick={linkto}>City Name</Button>
                        </Grid2>
                        <Grid2 xs={2} sm={4} md={4}>
                            <Button variant="outline-dark">Dark</Button>
                        </Grid2>
                        <Grid2 xs={2} sm={4} md={4}>
                            <Button variant="outline-dark">Dark</Button>
                        </Grid2>
                        <Grid2 xs={2} sm={4} md={4}>
                            <Button variant="outline-dark">Dark</Button>
                        </Grid2>
                        <Grid2 xs={2} sm={4} md={4}>
                            <Button variant="outline-dark">Dark</Button>
                        </Grid2>
                        <Grid2 xs={2} sm={4} md={4}>
                            <Button variant="outline-dark">Dark</Button>
                        </Grid2>
                        <Grid2 xs={2} sm={4} md={4}>
                            <Button variant="outline-dark">Dark</Button>
                        </Grid2>
                    </Grid2>
                </Offcanvas.Body>
            </Offcanvas>
        </>
    );
}

function FilterComponent({linkto}) {
    return (
        <>
            {/* <button onClick={ ()=> {handleChange("no")}}></button> */}
            {options.map((props, idx) => (
                <OffCanvasExample key={idx} func={linkto} {...props} />
            ))}
        </>
    );
}

export default FilterComponent; 

以上是我的 FilterComponent。我需要构建功能,这样当我点击我的'城市名'按钮我应该根据城市名称按字典顺序渲染 Home 中的所有卡片。 我知道我们必须从父母那里传递回调才能做到这一点,但我实际上不知道该怎么做。

以上是我的过滤按钮

以上是我要在其上添加功能的实际按钮

任何帮助,将不胜感激。

编辑: 我提到了这个链接React component not re-rendering on state change,问题是 React 没有重新渲染卡片,因为它没有意识到状态正在改变。更新的家庭代码如下。

function linkto(){
    
        let sortedCities= [...cities];
        sortedCities = sortedCities.sort((a, b) => {
            if (a.title < b.title) {
                return -1;
            }
            if (a.title > b.title) {
                return 1;
            }
            return 0;
        });
        // console.log(sortedCities);
        setCities(sortedCities)
}

【问题讨论】:

    标签: javascript reactjs


    【解决方案1】:

    你说过滤器,但看起来更像是排序,因为我没有看到任何用户输入以“过滤”城市名称的输入字段。在您的代码 let sortedStudents = cities.sort((a, b) =&gt; 中,您直接改变状态 cities,这在反应中是不好的做法,因此请将其更改为 let copiedCities = cities 之类的内容,然后进行排序。您可能希望在 FilterComponentSortComponent 中执行此排序,而不是在父组件中执行此排序,我认为您应该将其重命名为。您会将 cities 状态传递给子组件 (SortComponent),然后在其中进行排序。

    【讨论】:

    • 是的,我实际上尝试在 FilterComponent 中进行排序,然后在那里渲染 Card 组件(您可以在 Filter Component 的注释代码中看到它),但它不起作用。它按名称对城市进行排序,但无法呈现新的排序卡片
    • 您正在映射 options 而不是 cities。您需要重新组织组件的结构。也许您可以将您的代码包含在 Codesandbox 或 Stackblitz 中。很难理解发生了什么,因为现在太混乱了。
    • 感谢您的帮助,但我解决了问题并在上面进行了更新。
    【解决方案2】:

    您正在将回调 linkto 传递给位于 Home 的 Filtercomponent

     <FilterComponent onClick={linkto} {...props}></FilterComponent>
    

    之后你需要正确地解构它

    function FilterComponent({onClick, ...others}) {
        return (
            <>
                {/* <button onClick={ ()=> {handleChange("no")}}></button> */}
                {options.map((props, idx) => (
                    <OffCanvasExample key={idx} func={onClick} {...others} />
                ))}
            </>
        );
    }
    

    然后在Offcanvas

    function OffCanvasExample({ name, func, ...props}) {
        const [show, setShow] = useState(false);
        const handleClose = () => setShow(false);
        const toggleShow = () => setShow((s) => !s);
    
        return (
            <>
                <StyledButton variant="primary" onClick={toggleShow} className="me-2">
                    {name}
                </StyledButton>
                <Offcanvas show={show} onHide={handleClose} {...props}>
                    <Offcanvas.Header closeButton>
                        <Offcanvas.Title>Filters</Offcanvas.Title>
                    </Offcanvas.Header>
                    <hr></hr>
                    <Offcanvas.Body>
                        <Grid2 container spacing={2} columns={{ xs: 4, md: 16}}>
                            <Grid2 xs={2} sm={4} md={4}>
                                <Button variant="outline-dark" onClick={linkto}>City Name</Button>
                            </Grid2>
                            <Grid2 xs={2} sm={4} md={4}>
                                <Button variant="outline-dark">Dark</Button>
                            </Grid2>
                            <Grid2 xs={2} sm={4} md={4}>
                                <Button variant="outline-dark">Dark</Button>
                            </Grid2>
                            <Grid2 xs={2} sm={4} md={4}>
                                <Button variant="outline-dark">Dark</Button>
                            </Grid2>
                            <Grid2 xs={2} sm={4} md={4}>
                                <Button variant="outline-dark">Dark</Button>
                            </Grid2>
                            <Grid2 xs={2} sm={4} md={4}>
                                <Button variant="outline-dark">Dark</Button>
                            </Grid2>
                            <Grid2 xs={2} sm={4} md={4}>
                                <Button variant="outline-dark">Dark</Button>
                            </Grid2>
                        </Grid2>
                    </Offcanvas.Body>
                </Offcanvas>
            </>
        );
    }
    

    【讨论】:

    • 感谢您的帮助,但我解决了问题并在上面进行了更新。
    猜你喜欢
    • 2017-07-23
    • 2021-04-24
    • 1970-01-01
    • 1970-01-01
    • 2017-11-12
    • 1970-01-01
    • 1970-01-01
    • 2018-11-06
    • 2020-08-08
    相关资源
    最近更新 更多