reactjs - 使用 React,在使用 react-transition-group 时,在 StrictMode 中不推荐使用 findDOMNode 作为警告

标签 reactjs react-transition-group

我正在使用包 react-transition-group,我尝试在 CSSTransition 组件上使用 nodeRef Prop ,并在我的组件上添加了一个包装器,但我仍然收到有关 findDOMNode 的警告。
这是代码:

 <CSSTransition
        key={entry.id}
        timeout={500}
        classNames="timesheet-entry"
      >
          <TimesheetEntry
            taskOptions={taskOptions || []}
            deleteHandler={(event) => {
              deleteHandler(event, entry.id.toString());
            }}
            data={entry}
            dateChangeHandler={(date: Date) =>
              dateChangeHandler(date, entry.id)
            }
            hoursChangeHandler={(event) => hoursChangeHandler(event, entry.id)}
            taskCodeChangeHandler={(event, value) =>
              taskCodeChangeHandler(event, value, entry.id)
            }
          />
      </CSSTransition>
TimesheetEntry 组件的代码:
function TimesheetEntry(props: TimesheetEntryProps) {
  return (
    <div>
      <MuiPickersUtilsProvider utils={DateFnsUtils}>
        <KeyboardDatePicker
          label="Date"
          style={{ marginRight: '15px', height: '20px', marginTop: '-2px' }}
          disableToolbar
          variant="inline"
          format="MM/dd/yyyy"
          margin="normal"
          value={props.data.date}
          onChange={props.dateChangeHandler}
          size="small"
          KeyboardButtonProps={{
            'aria-label': 'change date',
          }}
        />
      </MuiPickersUtilsProvider>

      <Autocomplete
        size="small"
        style={{
          width: 300,
          display: 'inline-block',
          marginRight: '15px',
        }}
        options={props.taskOptions}
        getOptionLabel={(option) => option.name}
        getOptionSelected={(option, value) => {
          return option.id === value.id && option.name === value.name;
        }}
        onChange={props.taskCodeChangeHandler}
        renderInput={(params) => (
          <TextField {...params} label="Task" variant="outlined" />
        )}
      />

      <TextField
        size="small"
        style={{ marginRight: '15px', height: '20px' }}
        label="Hours"
        type="number"
        inputProps={{ min: 0.5, step: 0.5 }}
        onChange={props.hoursChangeHandler}
        InputLabelProps={{
          shrink: true,
        }}
      />

      <Button
        style={{ marginRight: '15px' }}
        variant="contained"
        color="secondary"
        size="small"
        startIcon={<DeleteIcon />}
        onClick={props.deleteHandler}
      >
        Delete
      </Button>
    </div>
  );
}

export default TimesheetEntry;
我还在代码框 here 中进行了一些类似的代码设置。
我尝试通过我的 TimesheetEntry 组件上的 div 包装器添加 nodeRef 和 ref 引用,但这似乎使动画行为不正确(添加新条目可以正常工作,但是当我尝试删除条目时,动画似乎不起作用不再)。我也在寻找一种无需在 TimesheetEntry 组件上创建 div 包装器的方法。

最佳答案

实际上有两个不同的findDOMNode CodeSandbox 演示中的警告:

  • 当您第一次添加或删除一个条目时,它源于直接使用 react-transition-group对于 TimesheetEntry .
  • 当您保存您的时间表时,它源于 react-transition-group 的间接使用通过 Material UI 的 Snackbar零件。

  • 不幸的是,您无法控制后者,所以让我们修复前者;您正在管理一个过渡列表 TimesheetEntry组件,但要正确实现 nodeRef ,每个元素都需要一个不同的 ref 对象,并且因为你不能在循环中调用 React 钩子(Hook)(参见 rules of hooks),你必须创建一个单独的组件:

    const EntryContainer = ({ children, ...props }) => {
      const nodeRef = React.useRef(null);
      return (
        <CSSTransition
          nodeRef={nodeRef}
          timeout={500}
          classNames="timesheet-entry"
          {...props}
        >
          <div ref={nodeRef}>
            {children}
          </div>
        </CSSTransition>
      );
    };
    

    您将环绕TimesheetEntry :
    const controls: JSX.Element[] = entries.map((entry: entry, index: number) => {
      return (
        <EntryContainer key={entry.id}>
          <TimesheetEntry
            deleteHandler={event => {
              deleteHandler(event, entry.id.toString());
            }}
            data={entry}
            dateChangeHandler={(date: Date) => dateChangeHandler(date, entry.id)}
            hoursChangeHandler={event => hoursChangeHandler(event, entry.id)}
            taskCodeChangeHandler={(event, value) =>
              taskCodeChangeHandler(event, value, entry.id)
            }
          />
        </EntryContainer>
      );
    });
    

    您说您已经尝试过这样的事情,但我怀疑您忘记转发 EntryContainer的 Prop 到CSSTransition ,这是至关重要的一步,因为这些是由 TransitionGroup 传递的。 .

    关于reactjs - 使用 React,在使用 react-transition-group 时,在 StrictMode 中不推荐使用 findDOMNode 作为警告,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/62187461/

    相关文章:

    reactjs - 使用 React.js 设置 useContext 和 useState 的正确方法?

    javascript - 如何使用 redux\redux-form 初始化独立的 Radio Button Group 组件检查属性状态

    javascript - 在 React.Intl <FormattedMessage> 上运行函数

    reactjs - 用户授权后如何在所有子组件之间传递状态?

    javascript - 在 react-transition-group 中退出延迟动画

    javascript - 从现有对象数组创建新对象数组时出现引用错误?

    react-transition-group - 如何淡出一个 react 组件,然后淡入另一个?

    reactjs - React v17.0.1 - 当 div 进入视口(viewport)时如何触发动画?

    javascript - 元素值在使用 react-transition-group 转换之前移动和更改

    javascript - 在与有状态值相关的两个组件之间进行转换