首页 > 解决方案 > 只要我拖放,无论映射到选中的功能如何,复选框都会设置为 true,我该如何解决这个问题?

问题描述

我正在使用 react-dropzone 模块实现它,以通过拖放实现文件上传。

只要我拖放,无条件复选框就会设置为 true,无论映射到选中的函数如何,我该如何解决这个问题?

import React, { useCallback, useState, useEffect } from 'react';
import { useDropzone } from 'react-dropzone';
import './FileAttach.scss';

function FileAttach(props) {
  // state
  const [indexesArrayForChekedList, setIndexesArrayForChekedList] = useState([]);
  const [filesToUpload, setFilesToUpload] = useState([]);
  const [allCheckBoxStatus, setallCheckBoxStatus] = useState(false);
  // 1122

  // all check 핸들링
  const allCheckHandeling = e => {
    const checked = e.target.checked;
    console.log(checked);

    if (checked) {
      console.log('채워');
      setallCheckBoxStatus(true);
      const indexArrayForFiles = filesToUpload.map(el => {
        return el.index;
      });
      console.log('인덱스 확인  : ', indexArrayForFiles);
      setIndexesArrayForChekedList(indexArrayForFiles);
    } else {
      console.log('비워');
      setallCheckBoxStatus(false);
      setIndexesArrayForChekedList([]);
    }
  };

  // 아직
  const moveRowUp = params => {
    console.log('indexesArrayForChekedList : ', indexesArrayForChekedList);
  };
  // 아직
  const moveRowDown = params => {
    console.log('indexesArrayForChekedList : ', indexesArrayForChekedList);
  };


  // checkbox 관련
  const confirmChecked = useCallback(
    index => {
      if (indexesArrayForChekedList.length === 0) return;

      console.log('index : ', index);
      console.log('체크 판단 함수 실행 확인 : ');

      if (indexesArrayForChekedList.includes(index)) {
        console.log('체크 상태');
        return false;
      } else if (!indexesArrayForChekedList.includes(index)) {
        console.log('체크 해제 상태');
        return true;
      }
    },
    [indexesArrayForChekedList],
  );

  const handleCheckedStatus = useCallback(
    (e, idx) => {
      console.log('e.target : ', e.target);
      console.log('e.target.checked : ', e.target.checked);
      console.log('idx : ', idx);
      const checked = e.target.checked;

      if (checked) {
        // 체크 상태였으면 해당 row의 index를 indexesArrayForChekedList 에서 제거
        const indexArrayForUpdate = indexesArrayForChekedList.filter(el => {
          console.log('체크 상태를 풀기 위해 해당 index를 제거 하겠습니다.');
          return el != idx;
        });
        setIndexesArrayForChekedList(indexArrayForUpdate);
      } else {
        console.log('체크 상태로 만들기 위해 index를 추가 하겠습니다');
        // 체크 상태가 아니였으면 indexesArrayForChekedList 에 해당 index.js를 추가
        setIndexesArrayForChekedList(prev => [...prev, idx]);
      }
    },
    [indexesArrayForChekedList],
  );

  const deleteRowByIndex = useCallback(
    idx => {
      console.log('idx :', idx);
      const afterDeleteRow = filesToUpload.filter(file => {
        return file.index != idx;
      });
      setFilesToUpload(afterDeleteRow);
    },
    [filesToUpload],
  );

  // dropzone 관련
  // drop event, 드롭 이벤트
  const onDrop = useCallback(
    acceptedFiles => {
      console.log('acceptedFiles : ', acceptedFiles);
      const filesData = acceptedFiles.map((file, index) => {
        return { index: filesToUpload.length + index, name: file.name, size: file.size };
      });
      setFilesToUpload(prev => [...prev, ...filesData]);
    },
    [filesToUpload],
  );

  const onDropAccepted = params => {
    console.log('드래그 accepted');
  };

  const { getRootProps, getInputProps, open, acceptedFiles } = useDropzone({
    noClick: true,
    noKeyboard: true,
    onDrop,
    noDragEventsBubbling: true,
    onDropAccepted,
  });

  // FileRow template
  const files = filesToUpload.map(file => (
    <div className="fileRow" key={file.index}>
      <div>
        {file.index}
        {/* 체크 박스 */}
        <input
          type="checkBox"
          onChange={e => handleCheckedStatus(e, file.index)}
          defaultChecked="false"
          checked={confirmChecked(file.index)}
        />
      </div>
      <div>{file.name}</div>
      <div>{file.size} (bytes)</div>
      <button type="button" onClick={() => deleteRowByIndex(file.index)}>
        삭제
      </button>
    </div>
  ));

  return (
    <div className="">
      <button type="button" onClick={open}>
        Open File Dialog
      </button>
      <div {...getRootProps({ className: 'dropzone' })}>
        <input {...getInputProps()} />
        {filesToUpload.length !== 0 ? (
          <div>
            {/*파일 로우의 헤더*/}
            <div className="fileRowHeader">
              <div>
                {/*모두 체크*/}
                <input
                  type="checkBox"
                  name="allCheck"
                  onClick={allCheckHandeling}
                  defaultChecked="false"
                  checked={allCheckBoxStatus}
                />
              </div>
              <div>
                <button onClick={moveRowUp}>위로</button>
                <button onClick={moveRowDown}>아래로&lt;/button>
              </div>
            </div>
            <div>{files}</div>
          </div>
        ) : (
          ''
        )}
      </div>
    </div>
  );
}

export default FileAttach;

代码沙箱: https ://codesandbox.io/s/recursing-dawn-i5t0g

github: https ://github.com/node-hyun/file-attach-dropzone

标签: reactjsevents

解决方案


在第 134 和 163 行,您defaultChecked="false"在这里使用false的是一个字符串。并且任何非空字符串(不管它包含什么)都是true. false不带引号使用。

const files = filesToUpload.map((file) => (
    <div className="fileRow" key={file.index}>
      <div>
        {file.index}
        {/* 체크 박스 */}
        <input
          type="checkBox"
          onChange={(e) => handleCheckedStatus(e, file.index)}
          defaultChecked={false} // <--- Its has to be a boolean
          checked={confirmChecked(file.index)}
        />
      </div>
      <div>{file.name}</div>
      <div>{file.size} (bytes)</div>
      <button type="button" onClick={() => deleteRowByIndex(file.index)}>
        삭제
      </button>
    </div>
  ));

签出这个更新的代码框


推荐阅读