简体   繁体   English

反应-我的情况部分起作用,为什么?

[英]REACT- My condition is working partially why?

In my json file from my api, I have a variable apply , If apply:0 , Then It should should print my data and If apply:1 , Then It should hide my data (ie row in my Table).在我的 api 的 json 文件中,我有一个变量apply ,如果apply:0 ,那么它应该打印我的数据,如果apply:1 ,那么它应该隐藏我的数据(即我的表中的行)。 Actually when I combine my 2 conditions, It is partially working : (applyStatus ? menus : menus.filter((i) => i.apply !== 1)) && (showGood ? menus : menus.filter((i) => i.taste !== "Good")) , ie Only the ...showGood ?... condition is working and the ...applyStatus?... not working.实际上,当我结合我的 2 个条件时,它是部分工作的: (applyStatus ? menus : menus.filter((i) => i.apply !== 1)) && (showGood ? menus : menus.filter((i) => i.taste !== "Good")) ,即只有...showGood ?...条件有效,而...applyStatus?...无效。

Whereas if I do only :而如果我只做:

<Table data={matchData && (applyStatus ? menus : menus.filter((i) => i.apply !== 1))> . <Table data={matchData && (applyStatus ? menus : menus.filter((i) => i.apply !== 1))> Then, I have my data where apply:0 are displayed.然后,我的数据显示在apply:0中。

What's wrong in my code please ?请问我的代码有什么问题?

export default function MenuDisplay() {
  const { menuId } = useParams();
  const [selected, setSelected] = useState({});
  const [hidden, setHidden] = useState({});
  const [menus, setMenus]=useState([])
  const [showGood, setShowGood] = useState(false);
  const [applyStatus, setApplyStatus] = useState(false);

  if (menus.apply === 0) {
    setApplyStatus(true)
}
if (menus.apply === 1) {
  setApplyStatus(false)
}

  useEffect (() => {
    axios.post("",{menuId:parseInt(menuId)})
        .then(res => {
            console.log(res)
            setMenus(res.data.menus)
            
        })
        .catch(err => {
            console.log(err)
        })
}, [menuId]);

useEffect (() => {
  const GoodMenus = menus.filter((i) => i.taste === "Good");
  const restOfMenus = menus.filter((i) => i.taste !== "Good");      
  setMenus([...GoodMenus, ...restOfMenus]);
}, [menus]);


  // If any row is selected, the button should be in the Apply state
  // else it should be in the Cancel state
  const buttonMode = Object.values(selected).some((isSelected) => isSelected)
    ? "apply"
    : "cancel";

  const rowSelectHandler = (id) => (checked) => {
    setSelected((selected) => ({
      ...selected,
      [id]: checked
    }));
  };

  const handleClick = () => {
    if (buttonMode === "apply") {
      // Hide currently selected items
      const currentlySelected = {};
      Object.entries(selected).forEach(([id, isSelected]) => {
        if (isSelected) {
          currentlySelected[id] = isSelected;
        }
      });
      setHidden({ ...hidden, ...currentlySelected });

      // Clear all selection
      const newSelected = {};
      Object.keys(selected).forEach((id) => {
        newSelected[id] = false;
      });
      setSelected(newSelected);
    } else {
      // Select all currently hidden items
      const currentlyHidden = {};
      Object.entries(hidden).forEach(([id, isHidden]) => {
        if (isHidden) {
          currentlyHidden[id] = isHidden;
        }
      });
      setSelected({ ...selected, ...currentlyHidden });

      // Clear all hidden items
      const newHidden = {};
      Object.keys(hidden).forEach((id) => {
        newHidden[id] = false;
      });
      setHidden(newHidden);
    }
  };

  const matchData = (
    menus.filter(({ _id }) => {
    return !hidden[_id];
  });

  const getRowProps = (row) => {
    return {
      style: {
        backgroundColor: selected[row.values.id] ? "lightgrey" : "white"
      }
    };
  };

  const data = [
    {
      Header: "id",
      accessor: (row) => row._id
    },
    {
      Header: "Name",
      accessor: (row) => (
        <Link to={{ pathname: `/menu/${menuId}/${row._id}` }}>{row.name}</Link>
      )
    },
    {
      Header: "Description",
      //check current row is in hidden rows or not
      accessor: (row) => row.description
    },
    {
      Header: "Dishes",
      //check current row is in hidden rows or not
      accessor: (row) => row.dishes,
      id: "dishes",
      Cell: ({ value }) => value && Object.values(value[0]).join(", ")
    },
    {
      Header: "Status",
      accessor: (row) => row.status
    },
    {
      Header: "Show",
      accessor: (row) => (
        <Toggle
          value={selected[row._id]}
          onChange={rowSelectHandler(row._id)}
        />
      )
    }
  ];

  const initialState = {
    sortBy: [
      { desc: false, id: "id" },
      { desc: false, id: "description" }
    ],
    hiddenColumns: ["dishes", "id"]
  };

  return (
    <div>
      <button type="button" onClick={handleClick}>
        {buttonMode === "cancel" ? "Cancel" : "Apply"}
      </button>
      show good
      <Toggle value = {showGood} onChange={() => setShowGood(!showGood)} />
      <Table
        data={matchData &&(applyStatus ? menus : menus.filter((i) => i.apply !== 1)) &&
        (showGood ? menus : menus.filter((i) => i.taste !== "Good"))}
        initialState={initialState}
        withCellBorder
        withRowBorder
        withSorting
        withPagination
        rowProps={getRowProps}
      />
    </div>
  );
}

Here my json from my api for menuId:1 :这里我的 json 来自我的 api 的menuId:1

[
  {
    "menuId": 1,
    "_id": "123ml66",
    "name": "Pea Soup",
    "description": "Creamy pea soup topped with melted cheese and sourdough croutons.",
    "dishes": [
      {
        "meat": "N/A",
        "vegetables": "pea"
      }
    ],
    "taste": "Good",
    "comments": "3/4",
    "price": "Low",
    "availability": 0,
    "trust": 1,
    "status": "Pending",
    "apply": 1
  },
  //...other data   

]

The problem is actually in the usage of your parenthesis.问题实际上在于括号的使用。 Your current logic looks like this.您当前的逻辑如下所示。

(applyStatus ? 
    menus : 
    menus.filter((i) => i.apply !== 1)
) && (showGood ? 
    menus : 
    menus.filter((i) => i.taste !== "Good")
)

If you simplify it it looks like如果你简化它看起来像

(Condition ? array : filteredArray) && (Condition ? array : filteredArray)

If you simplify it again it results in如果再次简化它会导致

array && array

When you are using && operator on two array like you are doing it will return you the second array which in your case is the array filter on i.taste !== "Good" .当您像您一样在两个数组上使用&&运算符时,它将返回第二个数组,在您的情况下,它是i.taste !== "Good"上的数组过滤器。

I tried to show it with a code sample below我试图用下面的代码示例来展示它

 const array = [{price:5, age:10},{price:3, age:8},{price:9, age:12},{price:12, age:13}]; const ageFiltered = array.filter(x => x.age < 11); const priceFiltered = array.filter(x => x.price > 4); console.log("Age filtered:" + JSON.stringify(ageFiltered)); console.log("Price filtered:" + JSON.stringify(priceFiltered)); const result = ageFiltered && priceFiltered; console.log("&& operator:" + JSON.stringify(result)); const doubleFiltered = array.filter(x => x.age < 11 && x.price > 4); console.log("Dobule filters:" + JSON.stringify(doubleFiltered));

To fix your issue your code must be update to be like this要解决您的问题,您的代码必须更新为这样

menus.filter(i => (applyStatus ? true : i.apply !== 1) && (showGood ? true : i.taste !== "Good") )

Your code is not working because && only return the value of the last operand.您的代码不起作用,因为&&只返回最后一个操作数的值。 So i think your code should be this所以我认为你的代码应该是这样的

            <Table
                data={
                    matchData && menus.filter(i => {
                        if (applyStatus) return true;
                        return i.apply !== 1;
                    }).filter(i => {
                        if (showGood) return true;
                        return i.taste !== 'Good'
                    })
                }
                initialState={initialState}
                withCellBorder
                withRowBorder
                withSorting
                withPagination
                rowProps={getRowProps}
            />
  if (menus.apply === 0) {
    setApplyStatus(true)
}
if (menus.apply === 1) {
  setApplyStatus(false)
}

from my understanding menus is an array so there is nothing like menus.apply so its either you loop the menus checking if apply is true.据我了解, menus是一个数组,所以没有什么像menus.apply这样的,所以它要么循环菜单检查 apply 是否为真。 then there is no need for ===0 just check if its true(1) or false(0).那么不需要===0只需检查它的真(1)还是假(0)。

if you want to display those that has apply you can sort them by using map just after fetching them like this如果你想显示那些已经应用的,你可以在像这样获取它们之后使用 map 对它们进行排序


useEffect (() => {
    axios.post("",{menuId:parseInt(menuId)})
        .then(res => {
            console.log(res)
            let data_ =res.data.menus
            let_apply_true = []
            let apply_false = []
       data_.map((data)=>{
if(data.apply){
let_apply_true.push(data)

}
//else will return those that are false
 let apply_false.push(data)
})



            setApplyMenus(let_apply_true)   //
            setNotApplyMenus(let apply_false)
            setMenus(res.data.menus)
            
        })
        .catch(err => {
            console.log(err)
        })
}, [menuId]);


//that is just one way 
// 

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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