简体   繁体   中英

Why onclick function isn't rendering (React.js)?

I'm working on building an e-commerce website in React. In which, there will be a navigation bar with all the categories and once a user clicked on a specific category, it will render all the products that belongs to the checked category in the same page. In the project I have two .js files which are NavBar.js where it contains all the stuff for the navigation bar and AllItems.js where all products are rendered.

My problem now, is that onclick in NavBar.js doesn't render AllItems.js . It works with console.log("sss") but it doesn't work with <AllItems/>

Here is my code in NavBar.js

function NavBar() {


    const [allCategories, setAllCategories] = useState([])
    const [currency, setCurrency] = useState([])
    

    useEffect(() => {

        fetchAnyQuery(
            `
            query{
                categories{
                name
                }
            }
        `).then(data => {
            setAllCategories( data.data.categories )
        })
    },[])

    // for currency options
    useEffect(() => {

        fetchAnyQuery(`
            query{
              currencies
            }
        `
        ).then(data => {
            setCurrency(data.data.currencies)
        })
    },[])


    return (
        <nav id = "NavBar">
            <div id="NavBar-content">

                <div className = "leftSide" id = "leftNav">

                    {allCategories.map((allCategories, index) => {

                        if (index == 0){
                            // return a checked tab

                            return(
                                <>
                                    <input className='radio-category' id={allCategories.name} type='radio' name="nav" onClick={
                                        function (){
                                            console.log("ssss");
                                            <AllItems/>

                                        }

                                    } checked/>
                                    <label htmlFor={allCategories.name} className='category-label'><h5 className="tab-text">{allCategories.name.toUpperCase()}</h5></label>
                                </>
                            )

                        }
                        else {
                            // return unchecked tab

                            return(
                                <>
                                    <input className='radio-category' id={allCategories.name} type='radio' name="nav" onClick={ function (){changeCategoryState(allCategories.name); <AllItems/>} } />
                                    <label htmlFor={allCategories.name} className='category-label'><h5 className="tab-text">{allCategories.name.toUpperCase()}</h5></label>
                                </>
                            )
                        }

                    })}
                </div>

                <div className = "centerSide">
                    {/*<a href="/">*/}
                    {/*    /!*<img src={logo} />*!/*/}
                    {/*    Logo*/}
                    {/*</a>*/}

                    <button onClick={function (){ console.log(getCategoryState()) }}>
                        Abo Kalb
                    </button>
                </div>

                <div className = "rightSide">

                    <select className="currencySelector" id="currencySelector">

                        {currency.map((currency, index) =>{

                            return(
                                <option value={ JSON.stringify(currency.indexOf(index)) }  >   {getSymbolFromCurrency(currency.toString()) + " " + currency.toString()} </option>

                            )
                        })}
                    </select>
                </div>
            </div>
        </nav>
    );
}

export default NavBar;

Also, here is my code for AllItems.js file:

function AllItems() {

    // The state that I want to use in NavBar.js
    // const [category, setCategory] = useState([getCategoryState()])
    const [products, setProducts] = useState([])



    useEffect(() => {

        fetchAnyQuery(
            `
                query{
                    categories{
                        name
                        products{
                            name
                            id
                        }
                    }
                }
        `
        ).then(data => {

            // Here I'm trying to do all  the required stuff

           // console.log(category)

        })


    },[])


    console.log("All Items RENDERED!!")

    return (
        <>

            <h1>{ getCategoryState() }</h1>

            <div className="itemContainer" id="itemContainer">

            </div>

        </>

    )
}

export default AllItems;

From what I understood, you want to render different categories' data based on which category is clicked, but you can not call a component on the click, that's not how React works. Instead set a state and render the component conditionally according to the state value, and set the state when the component needs to be rendered.

Assuming that you're fetching your items from a server, you will have to store that data in a state

const [allItems, setAllTems] = useState([])

Then add a state that will help you render your items conditionally

const [showAllItems, setShowAllItems] = useState(false)

In your JSX, use && to render your data when the state gets all the data

<> {showAllItems && <AllItems>} </>

if you're having troubles understanding how this works, I suggest you checking React documentations , it explains very well how you can manipulate the state

Use a parent component to manage the state. When you update the radio input in Nav update the state, and then filter the data based on that selection.

 const { useState } = React; function Example({ data }) { const [ items, setItems ] = useState(data); const [ selection, setSelection ] = useState(''); // When you click a button, set the selection state function handleClick(e) { setSelection(e.target.dataset.type); } // `filter` out the items you want to display // based on the selection function filteredItems() { return items.filter(item => item.type === selection); } return ( <div> <Nav> Dairy: <input onClick={handleClick} type="radio" data-type="dairy" name="food" /> Meat: <input onClick={handleClick} type="radio" data-type="meat" name="food" /> Vegetable: <input onClick={handleClick} type="radio" data-type="vegetable" name="food" /> </Nav> <Items items={filteredItems()} /> </div> ); }; // `map` over the filtered data function Items({ items }) { return items.map(item => <div>{item.name}</div>); } function Nav({ children }) { return children; } const data = [ { name: 'cow', type: 'meat' }, { name: 'bree', type: 'dairy' }, { name: 'chicken', type: 'meat' }, { name: 'sprout', type: 'vegetable' } ]; ReactDOM.render( <Example data={data} />, document.getElementById('react') );
 <script src="https://cdnjs.cloudflare.com/ajax/libs/react/17.0.2/umd/react.production.min.js"></script> <script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/17.0.2/umd/react-dom.production.min.js"></script> <div id="react"></div>

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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