Home > other >  React (Next.js) cannot get click event in a custom hook to change state of parent component
React (Next.js) cannot get click event in a custom hook to change state of parent component

Time:12-07

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. I've tried putting all logic from each within either file, but to no avail. Any advice appreciated!

Component Next.js page:

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:

    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;

CodePudding user response:

Move 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]);

CodePudding user response:

you need to lift "up the state".

by having useState inside , when using setIndustrySelected() tou are changing only the scope of the function itself.

You need to pass setIndustrySelected as a prop instead

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