Home > Blockchain >  setState() freezes React app after onClick
setState() freezes React app after onClick

Time:05-17

I am in the process of learning React, where I'm trying make a dropdown menu, where you can select different options. When you select an option, the corresponding data is supposed to be lifted to App.js, which I have done using useState() and props.

Unfortunfately, when clicking on the div with the onClick-function, the App freezes because of it infinitely refreshing the App.js view.

I have tested it quite a lot, and searched far and wide, but I can't seem to find a solution. When I moved the state from App.js to Header.js, I could make it work, but I need it lifted to App.js since I need to access it in other components.

I've provided the most relevant parts below.

App.js

const [summary, setSummary] = useState(undefined);

return (
        <>
            <Header user={user} setUser={setUser} auth={auth} provider={provider} summaries={summaries} current={summary} setSummary={setSummary} />
            <main className="bg-light">
                <Router>
                    <Switch>
                        <Route path="/" element={<Dashboard />} />
                    </Switch>
                </Router>
            </main>
        </>
    );

Header.js

function Header(props) {
    return (
        <header className="border-bottom border-black bg-white py-3">
            <div className="container">
                <div className="d-flex align-items-center justify-content-between">
                    <img src={Logo}></img>
                    {props.summaries ? <Dropdown items={props.summaries} current={props.current} setSummary={props.setSummary} /> : ''}
                    <div>{props.user ? props.user.displayName : 'Log venligst ind'}</div>
                    {props.user ? <Logout auth={props.auth} setUser={props.setUser} /> : <Login user={props.user} setUser={props.setUser} auth={props.auth} provider={props.provider} /> }
                </div>
            </div>
        </header>
    );
}

export default Header;

Dropdown.js

function Dropdown(props) {
    const [dropdown, setDropdown] = useState(false);
    const [selectedItem, setSelectedItem] = useState(undefined);
    const [selectedSubItem, setSelectedSubItem] = useState(undefined);
    const toggleOpen = () => setDropdown(!dropdown);

    return (
        <div className="dropdown">
            {/* {props.items.map((summary) => JSON.stringify(summary) '<br><br>')} */}
            <button className="btn btn-light-blue dropdown-toggle border-none" onClick={toggleOpen}>
                {props.current ? props.current.name : 'Vælg'}
            </button>
            <div className={`dropdown-menu ${dropdown ? 'show' : ''}`} aria-labelledby="dropdownMenuButton">
                <div className='row'>
                    <div className='col-4'>{props.items.map((summary) => <Item item={summary} selectItem={setSelectedItem} reset={setSelectedSubItem} key={summary.id} />)}</div>
                    <div className='col-4'>{selectedItem ? selectedItem.webProperties.map((subitem) => <Item item={subitem} setSummary={props.setSummary} selectItem={setSelectedSubItem} key={subitem.id} />) : ''}</div>
                    <div className='col-4'>{selectedSubItem ? selectedSubItem.profiles.map((subitem) => <Item item={subitem} setSummary={props.setSummary} key={subitem.id} />) : ''}</div>
                </div>
            </div>
        </div>
    );
}

export default Dropdown;

Item.js

function Item(props) {
    return (
        <div className="dropdown-item d-flex">
            <div onClick={props.selectItem ? () => {props.selectItem(props.item); if (props.reset) props.reset(undefined)} : undefined}>{props.item.name}</div>
            {props.setSummary ? <div className="btn btn-primary" onClick={() => props.setSummary(props.item)}>Vælg</div> : ''}
        </div>
    );
}

export default Item;

CodePudding user response:

props.setSummary() does not exist since you are passing that setState handler through a prop labeled new={props.setSummary}.

CodePudding user response:

function Header(props)
{
return <Dropdown {...props} />
}

function Dropdown(props)
{
return <Item key={subitem.id} {...props} />
}

function Item(props)
{
console.log(props);
return <div onClick={() => props.setSummary(props.key)}>Select</div>
}

Because of your passing props is not have the value of item. You've passed the value is key. Please check with console.log for every child element declaration. so you can avoid this kind of errors

  • Related