登录后React不会更新视图

时间:2020-02-09 23:34:07

标签: reactjs apollo

场景:

我有这个应用程序,每次用户通过前面的突变操作登录或注销时,我都必须自己刷新浏览器以更新导航栏,也许我在main.push之前缺少refetchQueries方法。然后,如果我通过单击导航栏上的退出按钮注销,则必须由我自己将浏览器刷新为在导航组件上工作的条件。

    // React apollo
    import { graphql } from 'react-apollo';
    import * as compose from 'lodash.flowright';

    // React router
    import { withRouter } from 'react-router-dom';

    // import mutations
    import mutations from './mutations';

    // React bootstrap
    import { Container, Row, Form, Button } from 'react-bootstrap';

    // Import Style
    import './style.css';



    class LoginForm extends React.Component {
        
        state = {
            login_credentials: {}
        }

        get_data = async(e) => {
            e.preventDefault();
            const { name, value } = e.target;
            const data = { [name]: value };
            const newData = { ...this.state.login_credentials, ...data };
            this.setState({
                login_credentials: newData
            });

        }
        
        submit = async(e) => {
            e.preventDefault();
            const { signinUser } = this.props;
            const { login_credentials } = this.state;
            
            try {
                let variables = login_credentials;
                const response = await signinUser({variables});
                const get_token = response.data.signinUser.token;
        
                // setting localStorage
                localStorage.setItem('token', get_token);
                
                this.props.history.push('/');
            } catch(error) {
                console.log(error);
            }

        
        }


        render() {

            return(
                <Fragment>
                <Container>
                    <Form className="form-container">
                        <h2 className="text-center pb-4">Ingreso</h2>
                        <Form.Group controlId="formBasicEmail">
                            <Form.Control name='email' onChange={e => this.get_data(e)} type="email" placeholder="Email" />
                        </Form.Group>

                        <Form.Group controlId="formBasicPassword">
                            <Form.Control name='password' onChange={e => this.get_data(e)} type="password" placeholder="Contraseña" />
                        </Form.Group>
                        <div className="text-center">
                            <Button className="button-login" variant="primary" onClick={e => this.submit(e)} type="submit">
                                Ingresa
                            </Button>
                        </div>
                    </Form>
                </Container>
                </Fragment>
            );
        }
    }

    export default compose(
        withRouter,
        graphql(mutations.signinUser, { name: 'signinUser' }),
    )(LoginForm);

我的路线在导航栏组件中:

    class NavbarLayout extends React.Component {
    
    signOut = async(e) => {
        e.preventDefault();
        const { signoutUser } = this.props;
        try {
            await signoutUser();
            localStorage.removeItem('token');
        } catch(error) {
            console.log(error);
        }
    }

    render() {
        const user_token = localStorage.getItem('token') || '';
        return(
            <Fragment>
                <Navbar bg="light" expand="lg">
                    <Navbar.Brand href="#home">Sample App</Navbar.Brand>
                    <Navbar.Toggle aria-controls="basic-navbar-nav" />
                    <Navbar.Collapse id="basic-navbar-nav">
                        <Nav className="ml-auto">
                        <Nav.Link><Link to="/">Home</Link></Nav.Link>
                        {user_token ? (
                            <Fragment>
                                <Nav.Link onClick={e => this.signOut(e)}>Salir</Nav.Link>
                                <Nav.Link>Publicar</Nav.Link>
                            </Fragment>
                        ):(
                        <Nav.Link><Link to="/sign-in">Entrar</Link></Nav.Link>
                        )}
                        </Nav>

                    </Navbar.Collapse>

                </Navbar>
                <Switch>
                    <Route path="/sign-in" component={LoginPage} />
                </Switch>
            
            </Fragment>
        );
    }
}

export default compose(
    graphql(mutations.signoutUser, { name: 'signoutUser' })
)(NavbarLayout)

1 个答案:

答案 0 :(得分:1)

所以这些看起来像是两个不同的问题。

登录方案中,您似乎有一条嵌套的路线。该页面不会重定向,因为您在同一子路由器中没有为/定义的路由。您需要将登录路线上移到与本国路线相同的级别。

退出场景中,这更多是一个一般的React问题,您不会做任何会触发渲染的事情。例如,如果您将登录状态更改为NavBar的本地状态,则可以在登录状态更改时强制组件重新呈现,例如

class NavbarLayout extends React.Component {
  constructor() {
    this.state = { loggedIn: false };
  }

  signOut = async(e) => {
    e.preventDefault();
    const { signoutUser } = this.props;
    try {
      await signoutUser();
      localStorage.removeItem('token');
      this.setState({ loggedIn: false });
    } catch(error) {
      console.log(error);
    }
  }

  ...
}

登录时,当然需要保持此状态同步,以使其正常工作,但您能理解。

相关问题