API调用后更新上下文值

时间:2019-01-05 06:25:07

标签: reactjs

我正在使用React 16.3上下文API,我正在使用上下文设置loggedin: booluser: Object的值,也使用PrivateRoute来登录用户。

这是一个简短的代码。

// AuthContext JS
import React from "react";

const AuthContext = React.createContext();

class AuthProvider extends React.Component {
    constructor(props) {
        super(props);

        this.state = {
            isLoggedIn: false,
            user      : null
        };

        this.setAuth = this.setAuth.bind(this);
    };

    setAuth(isLoggedIn = false, userData = null) {
        this.setState({
            isLoggedIn: isLoggedIn,
            user      : userData
        });
    }

    render() {
        return (
            <AuthContext.Provider
                value={ {...this.state, setAuth: this.setAuth} }>
                { this.props.children }
            </AuthContext.Provider>
        );
    }
}

const AuthUser = AuthContext.Consumer;

export {AuthContext, AuthProvider, AuthUser};

function PrivateRoute({component: Component, ...rest}) {
    return (
        <AuthUser>
            {
                ({isLoggedIn}) => (
                    <Route
                        { ...rest }
                        render={ props =>
                            (
                                isLoggedIn ? (
                                    <Component { ...props } />
                                ) : (
                                    <Redirect
                                        to={ {
                                            pathname: "/login",
                                            state   : {from: props.location}
                                        } }
                                    />
                                )
                            )
                        }
                    />
                )
            }
        </AuthUser>
    );
}

// App JS
class App extends Component {
    render() {
        return (
            <HashRouter>
                <AuthProvider>
                    <Switch>
                        <Route exact path="/login" name="Login Page" component={ Login } />
                        <Route exact path="/register" name="Register Page" component={ Register } />
                        <Route exact path="/404" name="Page 404" component={ Page404 } />
                        <Route exact path="/500" name="Page 500" component={ Page500 } />

                        <PrivateRoute path="/" component={ DefaultLayout } />
                    </Switch>
                </AuthProvider>
            </HashRouter>
        );
    }
}

export default App;

// Login JS
class Login extends Component {
    handleSubmit(values) {
        const opts = {
            "email"   : "test@example.com",
            "password": "test123"
        };

        let _this = this;

        fetch("API_URL", {
            method: "post",
            body  : JSON.stringify(opts)
        })
            .then(
                (response) => {
                    return response.json();
                }
            ).then(
            (data) => {
                _this.setState({
                    isAuth: true,
                    user  : data.data.user
                });
                _this.props.history.replace("/dashboard");

            }
        );
    }

    render() {
        console.log(this.state.isAuth);
        return (
            <AuthUser>
                {
                    ({isLoggedIn, setAuth}) =>
                       (
                                    <Redirect to="/dashboard" />
                                ) : ( <div > // Login Page </div>
                       )
                }
            </AuthUser>
        );
    }
}

如何更新/调用使用者的setAuth功能

如果我从渲染函数调用setAuth,它将发出警告并在setState上循环

任何帮助!

2 个答案:

答案 0 :(得分:1)

handleSubmit文件的Login函数中,而不是调用     this.setState({         isAuth:是的,         用户:data.data.user     }); 您应该调用上下文提供的setAuth函数,并在那里更新上下文中的用户身份验证和数据:

this.context.setAuth(true, data.data.user)

要使用this.context,您可能需要从使用上下文使用者更改为contextType

static contextType = AuthContext

答案 1 :(得分:0)

您已经实现了一个更高阶的组件,该组件可以帮助组件将上下文值用作道具。

以下withContextAsProps HOC提供了一个示例:

function withContextAsProps(Context, Component) {
    function WithContextAsProps(prop) {
       return (
         <Context>
          {value => <Component {...value} />}
         </Context>
       );
    }
    const componentName = Component.displayName || Component.name || 'Component';
    const contextName = Context.displayName || Context.name || 'Context';
    WithContextAsProps.displayName = `With${contextName}Context(${componentName})`;
    return WithContextAsProps;
}

Login组件中,HOC可用于使isAuth上下文使用者的setAuthAuthUser值在{{1 }}组件。

props