为了账号安全,请及时绑定邮箱和手机立即绑定

在呈现其他组件警告时无法更新组件

在呈现其他组件警告时无法更新组件

ITMISS 2022-09-29 17:43:03
我在反应中收到此警告:index.js:1 Warning: Cannot update a component (`ConnectFunction`) while rendering a different component (`Register`). To locate the bad setState() call inside `Register` 我转到堆栈跟踪中指示的位置并删除了所有设置状态,但警告仍然存在。这是否可能从 redux 调度中发生?我的代码:注册.jsclass 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 );函数,它触发我的寄存器窗体组件中由寄存器调用的警告.jshandleSubmit = 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()      }    }  }堆栈跟踪:
查看完整描述

5 回答

?
慕斯709654

TA贡献1840条经验 获得超5个赞

此警告是在 React V16.3.0 之后引入的。


如果您使用的是功能组件,则可以将 setState 调用包装到使用效果中。


不起作用的代码:


const HomePage = (props) => {

    

  props.setAuthenticated(true);


  const handleChange = (e) => {

    props.setSearchTerm(e.target.value.toLowerCase());

  };


  return (

    <div key={props.restInfo.storeId} className="container-fluid">

      <ProductList searchResults={props.searchResults} />

    </div>

  );

};

现在,您可以将其更改为:


const HomePage = (props) => {

  // trigger on component mount

  useEffect(() => {

    props.setAuthenticated(true);

  }, []);


  const handleChange = (e) => {

    props.setSearchTerm(e.target.value.toLowerCase());

  };


  return (

    <div key={props.restInfo.storeId} className="container-fluid">

      <ProductList searchResults={props.searchResults} />

    </div>

  );

};


查看完整回答
反对 回复 2022-09-29
?
慕尼黑8549860

TA贡献1818条经验 获得超11个赞

只是来这里是因为我刚刚遇到了这个问题,在我意识到我做错了什么之前,我花了一点时间去挖掘 - 我只是没有注意我如何编写我的功能组件。


我想我会在这里留下一个答案,以防有人来找,他们犯了和我一样简单的错误。


我正在这样做:


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>);

};

我只是忘记了使用,然后发送我的 redux 呼叫useEffectgetDateMatches()


太愚蠢了,我在所有其他组件中都一直在做的事情,哈哈。


所以它应该是:


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>);

};

简单而愚蠢的错误,但花了一段时间才意识到这一点,所以希望这有助于其他人解决这个问题。


查看完整回答
反对 回复 2022-09-29
?
慕哥6287543

TA贡献1831条经验 获得超10个赞

请仔细阅读错误消息,我的指向具有错误设置状态的登录组件。当我检查时,我有一个不是Arrow函数的onpress。

就像这样:

onPress={navigation.navigate("Home", { screen: "HomeScreen" })}

我把它改成了这样:

onPress={() => navigation.navigate("Home", { screen: "HomeScreen" }) }

我的错误消息是:

警告:在呈现其他组件 () 时无法更新组件 ()。若要在 内部找到错误的 setState() 调用,请按照登录(在登录屏幕.tsx:20)中的 https://reactjs.org/link/setstate-in-render 中所述的堆栈跟踪进行操作。ForwardRef(BaseNavigationContainer)SignInSignIn


查看完整回答
反对 回复 2022-09-29
?
慕娘9325324

TA贡献1783条经验 获得超5个赞

我通过将调度从寄存器组件呈现方法删除到组件卸载方法来解决此问题。这是因为我希望在重定向到登录页面之前发生此逻辑。一般来说,最好的做法是将所有逻辑放在渲染方法之外,这样我的代码以前写得很糟糕。希望这对将来的其他人有所帮助:)


我重构的寄存器组件:


class Register extends Component {


  componentWillUnmount() {

    // Reset register status to allow return to register page

    if ( this.props.registerStatus !== "" ) this.props.dispatch( resetRegisterStatus() )

  }


  render() {

    if( this.props.registerStatus === SUCCESS ) { 

      return <Redirect push to = {LOGIN}/>

    }

    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>

    );

  }

}


查看完整回答
反对 回复 2022-09-29
?
天涯尽头无女友

TA贡献1831条经验 获得超9个赞

如果使用效果无法在您的案例中使用,或者错误不是由于 Redux


我曾经将两个变量中的一个重定向到回调队列。setTimeoutuseState


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


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 (


查看完整回答
反对 回复 2022-09-29
  • 5 回答
  • 0 关注
  • 1024 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
微信客服

购课补贴
联系客服咨询优惠详情

帮助反馈 APP下载

慕课网APP
您的移动学习伙伴

公众号

扫描二维码
关注慕课网微信公众号