简体   繁体   English

React(Next.js)无法在自定义挂钩中获取单击事件以更改父组件的 state

[英]React (Next.js) cannot get click event in a custom hook to change state of parent component

In React (Next.js), I'm trying to make a click event in a custom hook change the state of parent component which would then display a list below the data table, but am unable to get it because the API call and data variable are in the parent component while the click event is in the custom hook child.在 React (Next.js) 中,我试图在自定义钩子中进行单击事件,更改父组件的 state,然后在数据表下方显示一个列表,但由于 API 调用和数据而无法获取它变量位于父组件中,而单击事件位于自定义挂钩子组件中。 I've tried putting all logic from each within either file, but to no avail.我尝试将每个文件中的所有逻辑都放在其中,但无济于事。 Any advice appreciated!任何建议表示赞赏!

Component Next.js page:组件 Next.js 页面:

import React, { useState } from "react";
import Routes from "../components/Routes";
import Table from "../components/useTable";

export const getStaticProps = async () => {
    const res = await fetch(
        "https://example.com/api/v4/...."
    );
    const data = await res.json();
    return {
        props: { data },
    };
};

const Industries = ({ data }) => {
    // Get companies, remove duplicates and sort
    const companyId = data.map((o) => o.name);
    const companies = data
        .filter(({ name }, index) => !companyId.includes(name, index + 1))
        .sort((a, b) => a.name.localeCompare(b.name));

    // Industry button click state
    const [industrySelected, setIndustrySelected] = useState("");

    // Get number of companies per industry
    const counted = companies.reduce((obj, v) => {
        obj[v.industryTitle] = (obj[v.industryTitle] || 0) + 1;
        return obj;
    }, {});

    // Convert object to array
    const array = Object.entries(counted);

    // Sort by descending order
    const sorted = array.sort((a, b) => b[1] - a[1]);

    return (
        <div>
            <Routes />
            <Table data={array} />
            <h2>
                <a id="list"></a>
                {industrySelected}
            </h2>
            <ol>
                {companies
                    .filter((item) => item.industryTitle === industrySelected)
                    .map((item) => (
                        <li key={item.symbol}>
                            {item.name} <u>({item.symbol})</u>
                        </li>
                    ))}
            </ol>
        </div>
    );
};

export default Industries;

Custom hook useTable.js:自定义钩子 useTable.js:

    import React, { useState } from "react";
    
    ...

const Table = (props) => {
    const { items, requestSort, sortConfig } = useSortableData(props.data);

    // Industry button click state
    const [industrySelected, setIndustrySelected] = useState("");

    const getClassNamesFor = (name) => {
        if (!sortConfig) {
            return;
        }
        return sortConfig.key === name ? sortConfig.direction : undefined;
  };
        return (
            <div>
                <table>
                    <thead>
                        ...
                    </thead>
                    <tbody>
                        {items.map((item) => (
                            <tr key={item[0]}>
                                <td>
                                    <a
                                        href="#list"
                                        onClick={() => {
                                            setIndustrySelected(item[0]);
                                        }}
                                    >
                                        {item[0]}
                                    </a>
                                </td>
                                <td>{item[1]}</td>
                            </tr>
                        ))}
                    </tbody>
          </table>
            </div>
        );
    };
    
    export default Table;

Move const [industrySelected, setIndustrySelected] = useState("");移动const [industrySelected, setIndustrySelected] = useState(""); to the Industries component and pass down the setIndustrySelected function as a prop to Table as onIndustrySelected and call it in the onClick instead of setIndustrySelected(item[0]);到 Industries 组件并将setIndustrySelected function 作为道具传递给 Table 作为onIndustrySelected并在 onClick 中调用它而不是setIndustrySelected(item[0]);

you need to lift "up the state".你需要提升“状态”。

by having useState inside, when using setIndustrySelected() tou are changing only the scope of the function itself.通过在内部使用 useState,当使用 setIndustrySelected() 时,您只会更改 function 本身的 scope。

You need to pass setIndustrySelected as a prop instead您需要将 setIndustrySelected 作为道具传递

<Table data={array} setIndustrySelected={setIndustrySelected} />

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

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