我正在使用React 16.3上下文API,我正在使用上下文设置loggedin: bool
和user: 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
上循环
任何帮助!
答案 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
上下文使用者的setAuth
和AuthUser
值在{{1 }}组件。
props