0

我是 React 的新手(实际上是编程世界),我只是发现我们根本不需要使用 componentWIllReceiveProps / getDerivedStateFromProps,但我有这个问题:

我有一个父组件 LoginForm,我在其中获取我的 API 并使用它的响应来重定向(如果成功),或者在登录失败时显示 Modal(LoginFailure 组件)。因此,我需要将我的父 LoginForm 传递给模态子 loginFailure 道具,该道具在 API 响应之后发生变化,当我的 LoginFailureComponent 已经呈现时,就好像它永远不知道父亲道具发生了变化。代码如下,抱歉太长了:

class LoginForm extends Component {
    constructor(props) {
        super(props);
        this.state = {
          username:"",
          password:"",
          remember:false,
          redirect: false,
          loginFailure: false
        };
        this.loginUser = this.loginUser.bind(this);
        this.handleInputChange = this.handleInputChange.bind(this);
    }

//Here i change the father state according to the API response:

    async loginUser() {
        await this.props.dispatch(fetchLogin(this.state));
            if (this.props.success) { //
                this.setState({
                    redirect: true
                })    
            } else {
                this.setState({
                    loginFailure: true
                })
            } 
      }


    handleInputChange(event) {
// unimportant code
    }

     handleForm(e){
           //more unimportant code but here i call the api:
         this.loginUser()
    }

    render() { 
// WHAT I WILL BE PASSING AS PROPS:
        const loginFailure = this.state.loginFailure;
        const redirect  = this.state.redirect;

        if (redirect) {
            return <Redirect to={`/profile/${this.props.token}`}/>;
        } else {   
            return ( <div className="text-center">
                <h3 className="mb-5">Login</h3>
                <Form className="w-100" onSubmit={(e)=>{this.handleForm(e)}}> 
                {/* Username: */}
                   //user input code
                {/* Password: */}
                    //password input code
                {/* Submit Button: */}
                   //submit button code
                {/*Login Failure component, HERE I PASS THE PROP ACCORDING TO THE STATE VALUE! */}
                    <LoginFailureModal loginFailure={loginFailure}></LoginFailureModal>
                </Form>
            </div>
            )
        }   
    }    
}

这是我的子组件,现在使用 willReceiveProps:

class LoginFailureModal extends Component {
    constructor(props) {
        super(props);
        this.state = {
          show: false, //i don't initialize with the props
          stopShowing: false //and i had to use this second state to STOP re rendering the modal every time i deleted some letter of my wrong input in the father
        }
    this.handleClose = this.handleClose.bind(this);
    }

    componentWillReceiveProps(nextProps) {
        this.setState({ 
            show: nextProps.loginFailure 
        }) 
      }

    handleClose(){
        this.setState({
            stopShowing: true
        })
    };  

    render() {     
        if (this.state.stopShowing) {
            return null
        } else {    
            return ( 
                <div key={this.props.loginFailure}>
                <Modal show={this.state.show} onHide={this.handleClose}>
                    <Modal.Header closeButton>
                        <Modal.Title>Login Failed!</Modal.Title>
                    </Modal.Header>
                    <Modal.Body>
                        Check your username and password and try again
                    </Modal.Body>
                </Modal>
                </div>
            )
       } 
    }   
}

我阅读了所有关于我们应该如何替换这些的 React 文档,但我无法将它应用到我的案例中,如果你能指导我解决这个问题,我将非常感激!

感谢社区!

4

2 回答 2

0

您可以使用React hooks并像这样处理您的 api:

// ... 
// It's like comoponentDidMount
useEffect({
   // Request api
}, []) 

// It's like componentWillReceiveProps
// If props.loginFailure was changed, React use this:
useEffect({
   // your conditions and ...
}, [props.loginFailure]) // props.loginFailure is a dependency. It's a flag to call inner code
于 2020-03-15T14:15:06.477 回答
0

因此,多亏了 Milad,我能够实现钩子,并且我的模态现在可以完美地工作了!这是代码:

const LoginFailureModalHooks = (props) => {
let [show, setShow] = useState(false);

useEffect(()=>{
    setShow(show=props.loginFailure)
}, [props.loginFailure]);

const handleClose = () => setShow(false);

//Render:
if (show===true) {
    return ( 
        <div key={props.loginFailure}>
        <Modal show={show} onHide={handleClose}>
            <Modal.Header closeButton>
                <Modal.Title>Login Failed!</Modal.Title>
            </Modal.Header>
            <Modal.Body>
                Check your username and password and try again
            </Modal.Body>
        </Modal>
        </div>
    );
} else {
    return null
}          
const LoginFailureModalHooks = (props) => {
let [show, setShow] = useState(false);

useEffect(()=>{
    setShow(show=props.loginFailure)
}, [props.loginFailure]);

const handleClose = () => setShow(false);

//Render:
if (show===true) {
    return ( 
        <div key={props.loginFailure}>
        <Modal show={show} onHide={handleClose}>
            <Modal.Header closeButton>
                <Modal.Title>Login Failed!</Modal.Title>
            </Modal.Header>
            <Modal.Body>
                Check your username and password and try again
            </Modal.Body>
        </Modal>
        </div>
    );
} else {
    return null
}          
}
export default LoginFailureModalHooks ;
于 2020-03-24T14:05:53.583 回答