【问题标题】:How to manage react state for a list of JSX.Elements correctly如何正确管理 JSX.Elements 列表的反应状态
【发布时间】:2020-02-13 18:57:04
【问题描述】:

我正在使用 react-hooks 来管理 JSX.Elements 列表。但是,一旦元素发生变化,尝试删除它会导致意外行为。

我曾尝试使用useReducer,按索引删除等,仍然出现意外的更新结果。

FolderPage.tsx

import React, { useState, useEffect } from 'react';
import { Button, Box, Grid } from 'grommet';
import { Add, Close } from 'grommet-icons';

import { Files } from '../Component/Files/Files';
import { ePub } from '../extension/ePub/ePub';

interface Props {}

export const FolderPage: React.FC<Props> = () => {
  const [state, setState] = useState([<Files openFileHandlers={[ePub]} />]);

  const newFolderPanel = () => setState(prev => prev.concat(<Files openFileHandlers={[ePub]} />));

  const removePanel = (panel: JSX.Element) => setState(prevState => prevState.filter(s => s !== panel));

  return (
    <div>
      <Box align="start" pad="xsmall">
        <Button icon={<Add />} label="New Folder Panel" onClick={newFolderPanel} primary />
      </Box>
      {state.map((s, index) => (
        <Grid key={index}>
          <Box align="end">
            <Button
              icon={<Close color="white" style={{ backgroundColor: 'red', borderRadius: '50%', padding: '.25rem' }} />}
              type="button"
              onClick={() => removePanel(s)}
            />
          </Box>
          {s}
        </Grid>
      ))}
    </div>
  );
};

例如,在使用中:

我应该如何更改我的代码,以便我的删除点击会删除匹配的元素?

【问题讨论】:

    标签: reactjs react-hooks react-state-management react-state


    【解决方案1】:

    有一种方法可以解决它。对于数组中的每个项目。不是直接存储项目,而是将其存储为 {id: yourAssignedNumber, content: item}。

    通过这种方式,您可以控制 id,并仅通过比较 id 来删除。这样,它就会正常工作。

    import React, { useState, useRef } from 'react';
    import { Button, Row, Col } from 'antd';
    
    import { Files } from '../Components/Files/Files';
    import { fileHandler } from '../model/fileHandler';
    
    interface Props {
      fileHandlers?: fileHandler[];
    }
    
    export const FolderPage: React.FC<Props> = ({ fileHandlers }) => {
      const [state, setState] = useState([{ key: -1, content: <Files fileHandlers={fileHandlers} /> }]);
      const key = useRef(0);
    
      const newFolderPanel = () =>
        setState(prev =>
          prev.concat({
            key: key.current++,
            content: <Files fileHandlers={fileHandlers} />
          })
        );
    
      const removePanel = (key: number) => setState(prevState => prevState.filter(s => s.key !== key));
    
      return (
        <Row>
          <Button type="primary" icon="plus" onClick={newFolderPanel} style={{ margin: '.75rem' }}>
            New Foldr Panel
          </Button>
          {state.map(({ key, content }) => (
            <Col key={key}>
              <div
                style={{
                  background: '#75ff8133',
                  display: 'grid',
                  justifyItems: 'end',
                  padding: '.5rem 1rem'
                }}>
                <Button onClick={() => removePanel(key)} icon="close" type="danger" shape="circle" />
              </div>
              {content}
            </Col>
          ))}
        </Row>
      );
    };
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2020-06-08
      • 1970-01-01
      • 1970-01-01
      • 2021-04-01
      • 1970-01-01
      • 2021-11-14
      • 2020-02-27
      相关资源
      最近更新 更多