React 博客系列 (2) React中的state和props更新

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/HYB2012/article/details/79234719

React中的state和props更新

github个人博客源码持续更新中。。。

在搭建个人博客的过程中,需要添加一个登陆窗体,登陆按钮和登陆表单分别在不同的组件,登陆btn在组件HeaderCustom,登陆窗体和表单在FormLogin,由登陆btn控制FormLogin的显示和隐藏,利用Redux进行状态管理。


HeaderCustom

  onLogin = () => {
    this.setState({
      visible: true
    },()=>{
      console.log("onLogin_state");
      console.log(this.state);
    });    
  }

render(){
    return(....
        <Menu.Item key="7" className="" style={ { lineHeight: '64px', position: "absolute", right: '0px', top: "0px" } }>
         <span onClick={ this.onLogin }> <Icon type="user" style={ { fontSize: 16, color: '#1DA57A' } }/>{ this.props.username } </span>
         <UserLoginFrom visible={ loginFormVisible }></UserLoginFrom>
        </Menu.Item>
    ...);
}

const mapStateToProps = (state) => {
  var adminAccess = state.reducer_login.adminAccess;
  var loginVisible = state.reducer_login.loginFormVisible;
  return {
    adminAccess: adminAccess,
    loginFormVisible: loginVisible
  }
}

FormLogin

  handleOk = () => {
        this._loginCheck()
        this.setState({
            loading: true
        });
        setTimeout(() => {
            this.setState({
                visible: false
            });
        }, 3000);
        this.props.changeLoginVisible({
            loginFormVisible:false
        })
    }

    handleCancel() {
        this.setState({
            visible: false
        });
        this.props.changeLoginVisible({
            loginFormVisible:false
        })
    }

    render() {
        const {getFieldDecorator} = this.props.form;
        const {visible, loading} = this.state;
        return (
            <Modal style={ { textAlign: "center" } } destroyOnClose={true} cancelText="取消" okText="登陆" visible={ visible } title="管理端登陆验证" onOk={ this.handleOk.bind(this) } onCancel={ this.handleCancel.bind(this) }>
              <Form onSubmit={ this.handleSubmit } className="login-form">
               ......
              </Form>
            </Modal>
            );
    }

const mapDispatchToProps = (dispatch) => {
    return {
      changeAccess: (assessToAdmin) => {
        dispatch(changeAdminAccess(assessToAdmin))
      },
      changeLoginVisible:(loginFormVisible)=>{
        dispatch(closeUserLoginForm(loginFormVisible))          
      }
    }
  }

解决方法1

在实施的过程中,遇到了setState方法和props更新的困扰,由于每次关闭窗体后,传递给HeaderCoustom的props为 loginFormVisible:false,出现了再次点击登陆按钮时窗体不显示的情况,经过分析才发现,props对象没有发生改变,render方法当然不会自动执行,故解决的办法是在props对象中加入时间戳:

const mapStateToProps = (state) => {
  var adminAccess = state.reducer_login.adminAccess;
  var loginVisible = state.reducer_login.loginFormVisible;
  //加入 key:(new Date()).getTime() 时间戳 每次传入的Props对象都不一样 组件都会重新渲染一次
  return {
    adminAccess: adminAccess,
    loginFormVisible: loginVisible,
    key:(new Date()).getTime()
  }
}

在实施的过程中,还发现了setState执行后,state对象不会立马改变,而是先执行render渲染后,才发生变化的。

  onLogin = () => {
    this.setState({
      visible: true
    },()=>{
      console.log("onLogin_state");
      console.log(this.state);//回调函数函数在render执行后再触发,此处打印的是变化后的state
    });
    console.log(this.state);//打印state变化前的对象
  }

解决方法2

放发一用到了redux刷新父级组价的props,这在深层次的嵌套中是最有效的传递状态的方法,但是在直接嵌套的父子组件中,感觉有些大材小用,父级组件可以直接绑定方法传递给子组件。

父级组件

  onLoginClose = () => {
    this.setState({
      visible: false
    }, () => {
      console.log("onLogin_close");
      console.log(this.state);
    });
  }

render(){
...
          <Menu.Item key="7" className="" style={ { lineHeight: '64px', position: "absolute", right: '0px', top: "0px" } }>
            <span onClick={ this.onLogin }> <Icon type="user" style={ { fontSize: 16, color: '#1DA57A' } }/>{ this.props.username } </span>
            <UserLoginFrom visible={ loginFormVisible } onClose={ this.onLoginClose.bind(this) }></UserLoginFrom>
          </Menu.Item>
}
...

子组件

    handleCancel() {
        this.setState({
            visible: false
        });
        console.log(this.props.onClose)
        this.props.onClose();
    }

将onClose传递给子组件 ,子组件状态改变时,反馈给父级组件改变父级自身的状态。

猜你喜欢

转载自blog.csdn.net/HYB2012/article/details/79234719