首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >当存储被更改时,未重新呈现React组件,既不自动也不通过强制更新进行重新呈现。

当存储被更改时,未重新呈现React组件,既不自动也不通过强制更新进行重新呈现。
EN

Stack Overflow用户
提问于 2021-11-03 08:51:37
回答 1查看 63关注 0票数 0

此功能组件应在更改存储中的值的每个项上显示带有复选框的排序列表。

由于某些原因,当商店被更改时,它不会重新呈现。没有重新渲染器,它(和整个应用程序)的工作非常不正常和半途而废。我怀疑这是因为存储对象保持不变,尽管有新的内容。但我不知道怎么解决它。我甚至在复选框处理程序中插入了一个强制更新,但由于某种原因,它也不起作用。

构成部分:

代码语言:javascript
复制
import React, { useState, useReducer } from 'react';
import { ReactSortable } from 'react-sortablejs';
import ListItem from '@mui/material/ListItem';
import Checkbox from '@mui/material/Checkbox';
import { connect } from 'react-redux';
import { setGameVisible, setGameInvisible } from '../store/actions/games';

interface IGamesListProps {
  games: [];
  setGameVisible: (id: string) => void;
  setGameInvisible: (id: string) => void;
}

interface ItemType {
  id: string;
  name: string;
  isVisible: boolean;
}

const GamesList: React.FunctionComponent<IGamesListProps> = ({games, setGameVisible, setGameInvisible}) => {
  const [state, setState] = useState<ItemType[]>(games);

  // eslint-disable-next-line
  const [ignored, forceUpdate] = useReducer(x => x + 1, 0); // this way of force updating is taken from the official React documentation (but even it doesn't work!)

  const onCheckboxChangeHandle = (id: string, isVisible: boolean) => {
    isVisible ? setGameInvisible(id) : setGameVisible(id);
    forceUpdate(); // doesn't work :(((
  }

  return (
    <ReactSortable list={state} setList={setState} tag='ul'>
      {state.map((item) => (
        <ListItem
          sx={{ maxWidth: '300px' }}
          key={item.id}
          secondaryAction={
            <Checkbox
              edge="end"
              onChange={() => onCheckboxChangeHandle(item.id, item.isVisible)}
              checked={item.isVisible}
            />
          }
        >
          {item.name}
        </ListItem>
      ))}
    </ReactSortable>
  );
};

export default connect(null, { setGameVisible, setGameInvisible })(GamesList);

减速机:

代码语言:javascript
复制
import { SET_GAMES, SET_GAME_VISIBLE, SET_GAME_INVISIBLE } from '../actions/games';

export const initialState = {
  games: [],
};

export default function games(state = initialState, action) {
  switch(action.type) {
    case SET_GAMES: {
      for(let obj of action.payload.games) {
        obj.isVisible = true;
      }
      return {
        ...state,
        games: action.payload.games,
      };
    }

    case SET_GAME_VISIBLE: {
      for(let obj of state.games) {
        if (obj.id === action.payload.id) {
          obj.isVisible = true;
        };
      }
      return {
        ...state,
      };
    }

    case SET_GAME_INVISIBLE: {
      for(let obj of state.games) {
        if (obj.id === action.payload.id) {
          obj.isVisible = false;
        };
      }
      return {
        ...state,
      };
    }
    
    default:
      return state;
  }
}

谢谢你的帮助!

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2021-11-03 10:04:26

注意:根据你给我的信息,我是带着这个问题的想法来的,但我在这里发了帖子,因为它将是解释性的,而且很长。

  • 首先,您不会在状态变化时通过mapStateToProps将新游戏传递到组件中,即使是这样,useState也不会使用新的游戏道具值进行非优先渲染。您必须使用useEffect并触发游戏更改,并将状态设置为本地.

此时,

必须发现内部状态是多余的,您可以删除它并完全依赖于redux状态。

代码语言:javascript
复制
const mapStateToProp = (state) => ({
  games: state.games // you may need to change the path
})

 connect(mapStateToProp, { setGameVisible, setGameInvisible })(GamesList);

  • 第二,你做的减缩器,改变了单个的游戏项目,而不是游戏列表本身。因为它是嵌套的,并且默认情况下引用检查是作为严格相等的引用签入-in redux state === state完成的。这可能不会引起问题,因为外部状态会发生变化,但我认为值得一提的是。

代码语言:javascript
复制
for(let obj of action.payload.games) {
  obj.isVisible = true; // mutating actions.payload.games[<item>]
}
return {
  ...state,
  games: [...action.payload.games], // add immutability for re-redenr
};

// or use map 
return {
  ...state,
  games: action.payload.games.map(obj => ({...obj, isVisible:true})),
};

  • 第三,您的forceUpdate确实会导致组件重新呈现,您可以通过添加console.log来测试它,但是如果组件的道具不改变,则不会重新绘制组件的整个子树,包括内部子树,这是因为性能问题。尽可能有效地做出反应。此外,如果项目和id的顺序不更改key

,则可以防止更改的优化层。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/69821988

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档