繁体   English   中英

反应useEffect不重新渲染

[英]React useEffect not rerendering

我正在尝试更改数组中的值并使用 useEffect 重新渲染组件,但 useEffect 未触发。 值正在更改,但调用 useState 无效。

const handleOptionClick = (e) => {

            var el = document.getElementById(e.currentTarget.id);
            var tar = el.getAttribute("data");
            
            var ans = awnsers;
            ans.map((res) => {
                if (res.Awnser === tar) {
                  res.IsChecked = !res.IsChecked;
                  return true;
                }
                return true;
              });
              setAwnsers(ans);
     }

useEffect(() => {
        console.log(awnsers);
    },[awnsers])

由于您在ans上执行map ,因此我认为它是一个数组。 Arrays 通过引用复制。 因此,为了对重新渲染awnsers做出反应,您必须创建一个新数组。

var ans = [...awnsers]; // or JSON.parse(JSON.stringify(awnsers)) for deep clone
            ans.map((res) => {
                if (res.Awnser === tar) {
                  res.IsChecked = !res.IsChecked;
                  return true;
                }
                return true;
              });
              setAwnsers(ans);

Awnsers一个错字吗? 你是说Answers吗?

React 在更新 state 时执行 Object.is 比较,如果先前和当前 state 的引用相同,则检查失败并且不会触发重新渲染

此外 map 返回数组的新引用,您不能改变原始数组,而是以不可变的方式更新它

const handleOptionClick = (e) => {

        var el = document.getElementById(e.currentTarget.id);
        var tar = el.getAttribute("data");
        
        var ans = awnsers; // Check for typo
        ans = ans.map((res) => {
            if (res.Awnser === tar) {
              {...res, IsChecked:!res.IsChecked};
            }
            return res;
          });
          setAwnsers(ans);
 }

PS您还可以使用功能 setState 方法来更新 state 因为您正在根据以前的值更新当前 state

  const handleOptionClick = (e) => {

        var el = document.getElementById(e.currentTarget.id);
        var tar = el.getAttribute("data");
        setAwnsers(prevAns => ans.map((res) => {
            if (res.Awnser === tar) {
              {...res, IsChecked:!res.IsChecked};
            }
            return res;
        }));
 }

You don't save the result of the array::map function that you save in state, so essentially the state reference values in the awnsers array don't change and the component won't re-render.

const handleOptionClick = (e) => {
  var el = document.getElementById(e.currentTarget.id);
  var tar = el.getAttribute("data");
        
  setAwnsers(prevAwnser => prevAwnser.map(res => ({
    ...res,
    IsChecked: res.Awnser === tar ? !res.IsChecked : res.IsChecked,
  })));
}

暂无
暂无

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

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