无法在反应引导模式中使用我的可重用反应组件

Posted

技术标签:

【中文标题】无法在反应引导模式中使用我的可重用反应组件【英文标题】:Unable to use my reusable react component inside react bootstrap modal 【发布时间】:2020-05-19 22:48:57 【问题描述】:

我已经创建了一个可重复使用的 textarea react 组件:

import React from 'react';
import '../form-input/form-input.styles.scss';

const TextAreaComponent = ( handleChange, label, ...otherProps ) => (
 <div className="group">
   <label htmlFor="comments">label</label>
   <textarea className='form-input m-0' id="comments" onChange=handleChange ...otherProps />
 </div>
); export default TextAreaComponent;

在任何其他组件中使用时都可以正常工作,但是当我在 react-bootstrap 模式中使用它时,每次按键时焦点都会从文本区域丢失,我必须再次单击它。我怀疑每次按键时状态都会发生变化,这是由于模态重新呈现而导致的,这就是为什么文本区域的焦点会丢失。

这是在 react bootstrap modal 中使用它的方式:

  import React,  useState  from 'react';
  import './callStatusCellRenderer.styles';
  import Button from 'react-bootstrap/Button';
  import Modal from 'react-bootstrap/Modal';
  import baseUrl from '../../../apiUtils/baseUrl';
  import CustomDatePicker from '../custom-datepicker/custom-datepicker.component';
  import SelectInputComponent from '../select-input/selectInput.component';
  import TextAreaComponent from '../textarea-input/textarea.component';
  import 
  ButtonContainer,
  CalendarContainer,
  InputContainer
   from './callStatusCellRenderer.styles';
  import axios from 'axios';

  const CallStatusRendererComponent = ( data ) => 
    const callStatusOption = ['Option A', 'Option B', 'Option C', 'Option D'];

  const [modalShow, setModalShow] = useState(false);
  const [status, setStatus] = useState(data.callStatusInfo.status);
  const [callDate, setCallDate] = useState(new Date(data.callStatusInfo.dt) || new Date());
  const [update, setUpdate] = useState(false);
  const [comments, setComments] = useState(data.callStatusInfo.comments);

  const callInfoS = 
    initialStatus: data.callStatusInfo.status,
    initialCallDate: data.callStatusInfo.dt || new Date(),
    initialComments: data.callStatusInfo.comments
  ;

  const getValue = () => 
    if (update) 
      return status;
     else 
      return callInfoS.initialStatus
    
  ;

  const onDateChange = dt => setCallDate(dt);

  const PopUpModal = (props) => 
    const onSubmit = async e => 
      e.preventDefault();
      props.onHide();
      const patchBody =  
        "status": status,
        "dt": callDate,
        'comments': comments
      ;
      const updateCallStatusUrl = `$baseUrl<<myAPIURL>>$data._id`;
      const config = 
        headers: 
          'Content-type': 'application/json',
          'Authorization': localStorage.getItem('token')
        
      ;
      await axios.patch(updateCallStatusUrl, callStatusInfo: patchBody, config);
      setUpdate(true);
    ;

    return (
        <Modal
            ...props
            size="lg"
            aria-labelledby="contained-modal-title-vcenter"
            centered
            animation=false
        >
          <Modal.Header closeButton>
            <Modal.Title id="contained-modal-title-vcenter">
              Update Call Info
            </Modal.Title>
          </Modal.Header>
          <Modal.Body>
            <h4>Call Details</h4>
            <InputContainer>
              <SelectInputComponent
                name="status"
                label="Status"
                value=status
                defaultOption="Select Status"
                options=callStatusOption
                onChange=(e) => setStatus(e.target.value)
              />
            </InputContainer>
            <TextAreaComponent name="comments" label="Comments" value=comments onChange=(e) => setComments(e.target.value)/>
            <CalendarContainer>
              <div className="mr-2"> Called Patient On:</div>
              <CustomDatePicker className="ml-4" dtVal=callDate handleChange=onDateChange/>
            </CalendarContainer>
          </Modal.Body>
          <Modal.Footer>
            <Button onClick=e => onSubmit(e)>Save</Button>
          </Modal.Footer>
        </Modal>
    );
  ;

  return (
      <>
        <div onClick=() => setModalShow(true)>
          <ButtonContainer>getValue()</ButtonContainer>
        </div>
        <PopUpModal
          show=modalShow
          onHide=() => setModalShow(false)
        />
      </>
  );
;export default CallStatusRendererComponent;

如何在可重复使用的文本区域中键入内容,而不会失去对每次按键的关注。

【问题讨论】:

尝试将唯一键添加到您的文本区域,如果键相同,它将告诉 DOM 这是相同的组件。 ***.com/questions/22573494/… 的可能重复项 我更新了我的代码并向 TextAreaComponent 添加了键: setComments( e.target.value)/> 但这仍然不起作用 【参考方案1】:

我能够解决这个问题,这里提到的这个 SO 问题和解决方案帮助了我: ReactJs component structure - Form inside modal

我基本上将 Modal 主体部分及其所有依赖状态和设置方法分离到一个单独的组件中

【讨论】:

以上是关于无法在反应引导模式中使用我的可重用反应组件的主要内容,如果未能解决你的问题,请参考以下文章

如何在反应中使用自定义可重用组件作为输入字段

react-flux 应用程序的可重用性/可扩展性问题

如何在 Gatsby 中为我的可重用组件返回特定图像?

React 中样式化组件的可重用性

React 中的可重用组件

在组件外部使用 redux 钩子来实现代码的可重用性