React useEffect不重新渲染

时间:2020-06-25 05:03:15

标签: reactjs react-hooks use-effect

我正在尝试更改数组中的值并使用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])

3 个答案:

答案 0 :(得分:0)

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

地图还返回了数组的新引用,您不得更改原始数组,而应以不可变的方式对其进行更新

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);
 }

P.S。您还可以使用功能性的setState方法来更新状态,因为您是根据先前的值更新当前状态的

  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;
        }));
 }

答案 1 :(得分:0)

您不会保存保存在状态中的array :: map函数的结果,因此awnsers数组中的状态引用值基本上不会改变,并且组件也不会重新呈现

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,
  })));
}

答案 2 :(得分:-1)

由于您正在map上进行ans,因此我将其视为一个数组。数组通过引用复制。因此,要做出反应以重新渲染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吗?