【问题标题】:Why onclick function isn't rendering (React.js)?为什么 onclick 函数不呈现(React.js)?
【发布时间】:2021-11-04 18:24:01
【问题描述】:

我正在用 React 构建一个电子商务网站。其中,将有一个包含所有类别的导航栏,一旦用户单击特定类别,它将在同一页面中呈现属于选中类别的所有产品。在项目中,我有两个 .js 文件,它们是 NavBar.js,其中包含导航栏的所有内容,而 AllItems.js 则呈现所有产品。

我现在的问题是,NavBar.js 中的 onclick 不会呈现 AllItems.js。它适用于console.log("sss"),但不适用于<AllItems/>

这是我在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;

另外,这是我的AllItems.js 文件代码:

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;

【问题讨论】:

  • 您可能应该有一个父组件来处理单击单选按钮的状态,并根据该状态呈现项目。
  • @Andy 我刚刚编辑了这个问题。有一些误解。欢迎再次阅读

标签: javascript html reactjs


【解决方案1】:

据我了解,您希望根据单击的类别来呈现不同类别的数据,但是您不能在单击时调用组件,这不是 React 的工作原理。而是设置一个状态并根据状态值有条件地渲染组件,并在需要渲染组件时设置状态。

假设您从服务器获取商品,您必须将数据存储在一个状态中

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

然后添加一个状态,帮助您有条件地呈现您的项目

const [showAllItems, setShowAllItems] = useState(false)

在你的 JSX 中,当 state 获取所有数据时,使用 && 来渲染你的数据

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

如果您在理解它的工作原理时遇到困难,我建议您查看React documentations,它很好地解释了您如何操纵状态

【讨论】:

  • Items 页面详情在 AllItems.js 中实现,Navbar.js 只是导航栏的实现,不可能将&lt;&gt;{showAllItems ? &lt;AllItems /&gt; : null}&lt;/&gt; 放入NavBar.js。这将显示导航栏中的所有内容
  • 我刚刚编辑了这个问题。有一些误解。欢迎再读一遍
  • 在这种情况下,您可以使用父组件来管理两个组件的状态,也可以使用 react 提供的上下文挂钩
【解决方案2】:

使用父组件来管理状态。当您更新 Nav 中的无线电输入时,更新状态,然后根据该选择过滤数据。

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>

【讨论】:

    猜你喜欢
    • 2021-10-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-02-28
    • 2014-11-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多