【问题标题】:React hooks component callback only has initial stateReact hooks 组件回调只有初始状态
【发布时间】:2020-04-11 21:41:16
【问题描述】:

我是反应钩子的新手,但是我有一个我认为相当直截了当的问题。这是我的父组件:

import React, { useState, useEffect } from 'react';
import DragAndDrop from '../DragAndDrop';
import Attachment from './Attachment';
import API from '../../services/api';
import '../../styles/components/attachments.scss';

const api = API.create();

const Attachments = ({attachments, type, typeId}) => {

  const [attachmentData, setAttachmentData] = useState([]);

  useEffect(() => {
    setAttachmentData(attachments);
  }, [attachments])

  function onUpload(files) {
    if (typeId) {
      api.AddAttachment(type, typeId, files).then(response => {
        let newAttachments = response.data.data;
        let newAttachmentData = attachmentData;
        newAttachmentData = newAttachmentData.concat(newAttachments);
        setAttachmentData(newAttachmentData);
      });
    }
  }

  return (
    <div className="attachments">
      <h3 className="attachments-title">Attachments</h3>
      <DragAndDrop onUpload={onUpload} />
      {attachmentData.map((attachment, index) => (
        <Attachment key={index} attachment={attachment} />
      ))}
    </div>
  );
}

export default Attachments;

attachments 是从父组件异步传入的,这就是我使用useEffect 函数的原因。

这一切都很好,并且在接收到数据时呈现子附件组件。

我有一个从 DragAndDrop 组件调用的回调 onUpload

import React, { useCallback } from 'react';
import {useDropzone} from 'react-dropzone';
import '../styles/components/dragAndDrop.scss';

const DragAndDrop = ({onUpload}) => {

  const onDrop = useCallback(acceptedFiles => {
    onUpload(acceptedFiles);
  }, [])

  const {getRootProps, getInputProps} = useDropzone({onDrop});

  return (
    <div>
      <div {...getRootProps({className: 'dropzone'})}>
        <input {...getInputProps()} />
        <p>Drag 'n' drop some files here, or click to select files</p>
      </div>
    </div>
  );

};

export default DragAndDrop;

我的问题是,当调用 Attachments 组件中的回调 onUpload 时,attachmentData 是初始值,它是一个空数组,而不是填充附件。在我的onUpload 函数中,我将新上传的内容发布到我的 API,然后以与其余附件相同的格式返回它们。然后我想将这些新附件连接到attachmentData。我需要attachmentData 在回调中填充值。为什么attachmentData 是初始状态[]?我如何让它发挥作用?

【问题讨论】:

    标签: javascript reactjs react-hooks


    【解决方案1】:

    问题是您在onUpload 中访问attachmentData,它在您使用它时会变得陈旧,因此要获取最新的attachmentData,您可以将回调函数传递给更新函数setAttachmentData,例如这个:

      function onUpload(files) {
        if (typeId) {
          api.AddAttachment(type, typeId, files).then(response => {
            let newAttachments = response.data.data;
            setAttachmentData(prevAttachmentData => ([...prevAttachmentData, ...newAttachments]));
          });
        }
      }
    

    如果您想访问onUpload 中的attachmentsData,您可以通过创建一个引用然后在附件数据更改时更新该引用来实现,这样您也不必将函数传递给setAttachmentsData

    const [attachmentsData, setAttachmentsData] = React.useState([]);
    const attachmentsDataRef = React.useRef(attachmentsData);
    
    // Update ref whenever state changes
    useEffect(() => {
      attachmentsDataRef.current = attachmentsData;
    }, [attachmentsData]);
    
    // Now in onUpload
     function onUpload(files) {
        // Here you can access attachmentsDataRef.current and you'll get updated state everytime
        if (typeId) {
          api.AddAttachment(type, typeId, files).then(response => {
            let newAttachments = response.data.data;
            setAttachmentData([...attachmentsDataRef.current, ...newAttachments]);
          });
        }
      }
    

    【讨论】:

    • 有什么方法可以在该函数中获取当前的 prevAttachmentData?
    • 对不起,我没关注,能详细点吗?
    • 有没有办法访问 onUpload 函数中的 attachmentData ?我们可以使用 prevAttachmentData 进行设置,但是我们可以获取 attachmentData 的新值吗?
    猜你喜欢
    • 1970-01-01
    • 2020-11-02
    • 2019-07-20
    • 2019-07-04
    • 1970-01-01
    • 2020-04-25
    • 2021-01-06
    • 2023-03-08
    • 2019-09-07
    相关资源
    最近更新 更多