Я не могу прекратить использование componentWIllReceiveProps / getDerivedStateFromProps - PullRequest
0 голосов
/ 15 марта 2020

Я новичок в React (и на самом деле в мире программирования), и я только что обнаружил, что нам вообще не нужно использовать componentWIllReceiveProps / getDerivedStateFromProps, но у меня есть эта проблема:

У меня есть родительский компонент , LoginForm, в котором я получаю свой API и использую его ответ для перенаправления, если оно выполнено успешно, или для отображения модального режима в случае сбоя входа в систему (компонент 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 о том, как мы должны заменить их, но я просто не смогу применить его к своему делу, я был бы очень благодарен, если бы вы могли помочь мне с этим вопросом!

Спасибо, сообщество!

Ответы [ 2 ]

0 голосов
/ 24 марта 2020

Так что благодаря Миладу я смог реализовать хуки, и мой модал теперь работает отлично! Это код:

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 ;
0 голосов
/ 15 марта 2020

Вы можете использовать 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
...