如何解除反应状态?

How to lift a REACT state?

所有。

我正在学习 REACT 并遇到了一个问题。

基本上,我想将一个“处理状态”函数移动到父组件 (App),并在子组件 (MenuItem) 中调用它。

在 App 组件中,我创建了一个函数“handleClickFavorite”来处理变量“isFavorite”的状态。

在 MenuItem 组件中,我将函数和变量都作为 props 传递,并在 onClick 事件中使用它们。基本上,每次单击按钮或 div.

时,我都想在项目的两个 CSS 类(最喜欢和不最喜欢)之间切换

MenuList 部分只获取数组的元素,这些元素呈现在div在 MenuItem 中,并映射它们

应用组件:

import React, { useState } from 'react';
import './App.css';
import MenuList from './components/MenuList';
import foodItems from './components/data.js';

const App = (props) => {
  const [isFavorite, setIsFavorite] = useState(props.isFavorite);

  const handleClickFavorite = () => {
    setIsFavorite(!isFavorite);
  };

  return (
    <div>
      <h1>Wild Restaurant Menu</h1>
      <MenuList
        isFavorite={isFavorite}
        handleClickFavorite={handleClickFavorite}
        foodItems={foodItems}
      />
    </div>
  );
};

export default App;

菜单列表组件:

import React from 'react';
import MenuItem from './MenuItem';

function MenuList({ foodItems }) {
  console.log(foodItems);
  return (
    <div>
      {foodItems.map((element, index) => (
        <MenuItem {...element} key={index} />
      ))}
    </div>
  );
}

export default MenuList;

菜单项组件:

import React, { useState } from 'react';
import '../App.css';

function MenuItem(props) {
  //create a state isFavorite that has the inital value of isFavorite that comes from the props
  const {
    itemName,
    description,
    foodImage,
    price,
    isFavorite,
    handleClickFavorite,
  } = props;

  return (
    <div className="itemContainer">
      <div className="leftContainer">
        <div className="imgContainer">
          {/* the image will receive the url src from the props */}
          <img src={foodImage} alt="" />
        </div>
        <div className="itemDescription">
          {/* the h3 will receive the item name from the props */}
          <h3>{itemName}</h3>
          {/* the p will receive the item description from the props */}
          <p>{description}</p>
        </div>
      </div>
      <div className="rightContainer">
        {/* the div will receive the item price from the props */}
        <div>{price} EUR</div>

        {/* the div with id favorite will have 2 attributes:
                - onClick, will call the method handleClickFavorite,
                - classname, that will be conditionally rendered, depending on the value of isFavorite from the component's state
            */}
        <div
          id="favorite"
          onClick={handleClickFavorite}
          className={isFavorite ? 'isFavorite' : 'notFavorite'}
        />
      </div>
    </div>
  );
}

export default MenuItem;

这是我第一次在这里提问,所以请保持温和。我尝试了很多解决方案,但不幸的是没有任何效果。 isFavorite 的状态没有改变,类.

也没有改变

有人可以帮助我吗?

你的代码之所以不能如你所愿,是因为你没有给MenuItem写props。 您已经正确地将道具写入 MenuList,因此您需要以相同的方式将 useState isFavorite 和 setIsFavorite 从 MenuList 分派到 MenuItem。 只需写入 function MenuList({ foodItems }) also isFavorite 和 setIsFavorite。 所以它将是 function MenuList({ foodItems, isFavorite, setIsFavorite }) 并将它们作为道具发送给 MenuItem,就像您对 MenuList 所做的那样。

一些笔记。如果不喜欢2级道具钻取,可以关注状态管理器(redux、mob x、effector)或者hook useContext。所以你可以在你所有的项目中获取数据而不需要道具。

您实际上并没有将 props 传递给 children。在你的 MenuList 组件中,你只有 foodItems 作为道具。所以你不能得到你需要的其他道具。这些是 isFavoritehandleClickFavorite.

您的代码块和更改。

function MenuList({ foodItems }) {
  console.log(foodItems);
  return (
    <div>
      {foodItems.map((element, index) => (
        <MenuItem {...element} key={index} />
      ))}
    </div>
  );
}


// Updated code
function MenuList({ foodItems, isFavorite, handleClickFavorite}) {
  console.log(foodItems);
  return (
    <div>
      {foodItems.map((element, index) => (
        <MenuItem {...element} key={index} 
            isFavorite={isFavorite}
            handleClickFavorite={handleClickFavorite}
        />
      ))}
    </div>
  );
}

另外,如果你有一棵有很多深度的树,你需要在每一层为所有 children 传递所有道具。这可能会令人恼火,并会降低性能和代码可读性方面的代码质量。

在这种情况下,您可以使用 React 上下文 API 或 3rd 方库,例如 redux。

然后你通过 {...element}<MenuItem {...element} key={index} />MenuItem 组件中将 element 传播到道具中。 但我认为这可能不太好,因为 MenuItem 在实践中可能有更多的道具或数据。所以我建议像 <MenuItem key={index} element={element} />.

这样使用它

然后您可以在 MenuItem 中访问 element,如下所示。

function MenuItem(props) {
  //create a state isFavorite that has the inital value of isFavorite that comes from the props
  const {
    element: {
        itemName,
        description,
        foodImage,
        price,
    },
    isFavorite,
    handleClickFavorite,
  } = props;

...
}

希望对您有所帮助!