我得到这个警告在反应:

index.js:1 Warning: Cannot update a component (`ConnectFunction`) 
while rendering a different component (`Register`). To locate the 
bad setState() call inside `Register` 

我去了堆栈跟踪中指出的位置,并删除了所有设置状态,但警告仍然存在。这可能发生在redux调度?

我的代码:

register.js

class Register extends Component {
  render() {
    if( this.props.registerStatus === SUCCESS) { 
      // Reset register status to allow return to register page
      this.props.dispatch( resetRegisterStatus())  # THIS IS THE LINE THAT CAUSES THE ERROR ACCORDING TO THE STACK TRACE
      return <Redirect push to = {HOME}/>
    }
    return (
      <div style = {{paddingTop: "180px", background: 'radial-gradient(circle, rgba(106,103,103,1) 0%, rgba(36,36,36,1) 100%)', height: "100vh"}}>
        <RegistrationForm/>
      </div>
    );
  }
}

function mapStateToProps( state ) {
  return {
    registerStatus: state.userReducer.registerStatus
  }
}

export default connect ( mapStateToProps ) ( Register );

函数,该函数触发了由register.js调用的registerForm组件中的警告

handleSubmit = async () => {
    if( this.isValidForm() ) { 
      const details = {
        "username": this.state.username,
        "password": this.state.password,
        "email": this.state.email,
        "clearance": this.state.clearance
      }
      await this.props.dispatch( register(details) )
      if( this.props.registerStatus !== SUCCESS && this.mounted ) {
        this.setState( {errorMsg: this.props.registerError})
        this.handleShowError()
      }
    }
    else {
      if( this.mounted ) {
        this.setState( {errorMsg: "Error - registration credentials are invalid!"} )
        this.handleShowError()
      }
    }
  }

堆栈跟踪:


当前回答

我的案例是使用setState回调,而不是setState + useEffect

坏❌

  const closePopover = useCallback(
    () =>
      setOpen((prevOpen) => {
        prevOpen && onOpenChange(false);
        return false;
      }),
    [onOpenChange]
  );

好✅

  const closePopover = useCallback(() => setOpen(false), []);

  useEffect(() => onOpenChange(isOpen), [isOpen, onOpenChange]);

其他回答

我的例子。

带有错误的代码:

<Form
    initialValues={{ ...kgFormValues, dataflow: dataflows.length > 0 ? dataflows[0].df_tpl_key : "" }}
    onSubmit={() => {}}
    render={({values, dirtyFields }: any) => {
      
      const kgFormValuesUpdated = {
        proj_key: projectKey,
        name: values.name,
        description: values.description,
        public: values.public,
        dataflow: values.dataflow,
        flavours: flavoursSelected,
        skipOCR: values.skipOCR
      };

      if (!_.isEqual(kgFormValues, kgFormValuesUpdated)) {
        setNewKgFormValues(kgFormValuesUpdated);
      }

工作代码:

 <Form
    initialValues={{ ...kgFormValues, dataflow: dataflows.length > 0 ? dataflows[0].df_tpl_key : "" }}
    onSubmit={() => {}}
    render={({ values, dirtyFields }: any) => {
      useEffect(() => {
        const kgFormValuesUpdated = {
          proj_key: projectKey,
          name: values.name,
          description: values.description,
          public: values.public,
          dataflow: values.dataflow,
          flavours: flavoursSelected,
          skipOCR: values.skipOCR
        };

        if (!_.isEqual(kgFormValues, kgFormValuesUpdated)) {
          setNewKgFormValues(kgFormValuesUpdated);
        }
      }, [values]);

      return (

我只是遇到了这个问题,在我意识到我做错了什么之前,我花了一些时间去挖掘——我只是没有注意我是如何写我的函数组件的。

我是这样做的:

const LiveMatches = (props: LiveMatchesProps) => {
  const {
    dateMatches,
    draftingConfig,
    sportId,
    getDateMatches,
  } = props;

  if (!dateMatches) {
    const date = new Date();
    getDateMatches({ sportId, date });
  };

  return (<div>{component stuff here..}</div>);
};

在分派getDateMatches()的redux调用之前,我刚刚忘记了使用useEffect。

所以它应该是:

const LiveMatches = (props: LiveMatchesProps) => {
  const {
    dateMatches,
    draftingConfig,
    sportId,
    getDateMatches,
  } = props;

  useEffect(() => {
    if (!dateMatches) {
      const date = new Date();
      getDateMatches({ sportId, date });
    }
  }, [dateMatches, getDateMatches, sportId]);

  return (<div>{component stuff here..}</div>);
};

使用上面的一些答案,我摆脱了以下错误:

from

if (value === "newest") {
  dispatch(sortArticlesNewest());
} else {
  dispatch(sortArticlesOldest());
}

这段代码位于我的组件顶层

to

    const SelectSorting = () => {
  const dispatch = useAppDispatch();

  const {value, onChange} = useSelect();

  useEffect(() => {
    if (value === "newest") {
      dispatch(sortArticlesNewest());
    } else {
      dispatch(sortArticlesOldest());
    }
  }, [dispatch, value]);

使用React和材质UI (MUI) 我改变了我的代码:

<IconButton onClick={setOpenDeleteDialog(false)}>
        <Close />
      </IconButton>

To:

<IconButton onClick={() => setOpenDeleteDialog(false)}>
        <Close />
      </IconButton>

简单的修理

如果useEffect不能在您的情况下使用或如果错误不是由于Redux

我使用setTimeout将两个useState变量中的一个重定向到回调队列。

我有一个父组件和一个子组件,每个组件中都有useState变量。解决方案是使用setTimeout来包装useState变量:

setTimeout(() => SetFilterData(data), 0);

在下面的例子

父组件

import ExpenseFilter from '../ExpensesFilter'
    
function ExpensesView(props) {
    
    const [filterData, SetFilterData] = useState('')
    
    const GetFilterData = (data) => {
       // SetFilterData(data);

       //*****WRAP useState VARIABLE INSIDE setTimeout WITH 0 TIME AS BELOW.*****
       setTimeout(() => SetFilterData(data), 0);
    
    }
    
    const filteredArray = props.expense.filter(expenseFiltered => 
      expenseFiltered.dateSpent.getFullYear().toString() === filterData);
    
    
    return (
    <Window>
      <div>
        <ExpenseFilter FilterYear = {GetFilterData}></ExpenseFilter>

子组件

const ExpensesFilter = (props) => {
    
    const [filterYear, SetFilterYear] = useState('2022')
    
    const FilterYearListener = (event) => {
        event.preventDefault()
        SetFilterYear(event.target.value)
    }
    
    props.FilterYear(filterYear)
    
    return (